[
  {
    "path": "LICENSE",
    "content": "MIT License\n\nCopyright (c) 2022 Zetaspace\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "Patcher/安装.CMD",
    "content": "@echo off\nchcp 65001>nul\ncolor f0\nif not exist \"%~dp0组策略文件\\安装组策略.cmd\" echo 检测到文件缺失，请解压后运行！&pause&exit\necho 请允许管理员权限以便安装，谢谢。\n%1 mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"cmd.exe\",\"/c %~s0 ::\",\"\",\"runas\",1)(window.close)&&exit\ncd /d %~dp0\nmode con cols=20 lines=10\n\nfor /f \"tokens=2 delims= \" %%i in ('dir /b^|findstr PowerToys') do set modver=%%i\nset modfulver=%modver%\nset softname=PowerToys\n\ntitle 修改 %softname%\nfor /l %%i in (1,20,40) do mode con cols=20 lines=%%i\nfor /l %%i in (20,40,160) do mode con cols=%%i lines=40\n:start\ncolor f0\nmsg %username% /time:1 /v /w 欢迎使用 Zetaloop 的 %softname% 修改！>nul\ncolor 07\n\nfor /f \"skip=2 tokens=2,*\" %%a in ('reg query \"HKCR\\powertoys\\shell\\open\\command\"') do set ptpath=%%b\nif %errorlevel%==1 echo 警告：找不到注册表信息！你可能未安装 %softname%&set /p =请按任意键退出. . . &exit\nset ptpath=%ptpath:~1,-6%\nfor /f \"delims=\" %%a in ('echo %ptpath%') do set installpath=%%~dpa\nfor /f \"usebackq delims=\" %%a in (`mshta vbscript:CreateObject(\"Scripting.FileSystemObject\"^).GetStandardStream(1^).WriteLine(CStr(CreateObject(\"Scripting.FileSystemObject\"^).GetFileVersion(\"%ptpath%\"^)^)^)(window.close^)`) do set installver=%%a\nfor /f \"tokens=1,2,3 delims=.\" %%a in ('echo %installver%') do set installver=%%a.%%b.%%c\necho.\necho 修改包版本 %modfulver%\necho %softname% 版本 %installver%\nif not \"%modfulver%\"==\"%installver%\" echo ·警告：汉化包版本不对应！&msg %username% /v /w 警告：汉化包版本不对应，强行安装可能导致报错闪退！>nul\necho.\necho 安装目录 %installpath%\nif not exist \"%installpath%PowerToys.exe\" echo 警告：安装目录检测失败！ %&set /p =请按任意键退出. . . &exi\necho.\necho 安装过程：\n::\necho ·解除安装目录的占用\n::\necho ·复制汉化文件到软件目录\necho.\necho 为解除文件占用，将会重启 Windows 资源管理器\necho ---------------------------------------------------\nchoice /c thequickbrownfxjmpsvlazydg /n /m \"确认无误后，按下 Y 开始：\"\nif %errorlevel%==24 goto install\n::if %errorlevel%==22 goto installarm64\necho 取消安装。退出安装器...\nchoice /t 1 /d n >nul\nexit\n\n:installarm64\nset modver=%modver% ARM64\n\n:install\necho 开始安装！\nif exist \"%tmp%\\PowerToys.NewPlus.ShellExtension.dll_*\" del \"%tmp%\\PowerToys.NewPlus.ShellExtension.dll_*\"\nif exist \"%tmp%\\PowerToys.FileLocksmithExt.dll_*\" del \"%tmp%\\PowerToys.FileLocksmithExt.dll_*\"\nif exist \"%tmp%\\PowerToys.FileLocksmithContextMenu.dll_*\" del \"%tmp%\\PowerToys.FileLocksmithContextMenu.dll_*\"\nif exist \"%tmp%\\PowerToys.PowerRenameExt.dll_*\" del \"%tmp%\\PowerToys.PowerRenameExt.dll_*\"\nif exist \"%tmp%\\PowerToys.PowerRenameContextMenu.dll_*\" del \"%tmp%\\PowerToys.PowerRenameContextMenu.dll_*\"\nif exist \"%tmp%\\PowerToys.RegistryPreviewExt.dll_*\" del \"%tmp%\\PowerToys.RegistryPreviewExt.dll_*\"\nif exist \"%tmp%\\PowerToys.ImageResizerExt.dll_*\" del \"%tmp%\\PowerToys.ImageResizerExt.dll_*\"\n:chcp 936>nul\ncall :killpt\nrmdir /s /q %installpath%WinUI3Apps\\Assets\\NewPlus\\Templates\nxcopy \".\\%softname% %modver%\\*\" \"%installpath%\" /e /y\nif %errorlevel%==0 goto success\necho 尝试解锁...\ntaskkill /f /im explorer.exe\nrmdir /s /q %installpath%WinUI3Apps\\Assets\\NewPlus\\Templates\nxcopy \".\\%softname% %modver%\\*\" \"%installpath%\" /e /y\nif %errorlevel%==0 start explorer&goto success\nstart explorer\necho 尝试移走一些文件...\necho 这些文件放到了系统临时文件夹。\n::\necho 你可能需要重启电脑来使汉化生效。\n::\nif exist \"%tmp%\\PowerToys.NewPlus.ShellExtension.dll_*\" del \"%tmp%\\PowerToys.NewPlus.ShellExtension.dll_*\"\nif exist \"%installpath%WinUI3Apps\\PowerToys.NewPlus.ShellExtension.dll\" move \"%installpath%WinUI3Apps\\PowerToys.NewPlus.ShellExtension.dll\" \"%tmp%\\PowerToys.NewPlus.ShellExtension.dll_%random%.tmp\"\nif exist \"%tmp%\\PowerToys.FileLocksmithExt.dll_*\" del \"%tmp%\\PowerToys.FileLocksmithExt.dll_*\"\nif exist \"%installpath%WinUI3Apps\\PowerToys.FileLocksmithExt.dll\" move \"%installpath%WinUI3Apps\\PowerToys.FileLocksmithExt.dll\" \"%tmp%\\PowerToys.FileLocksmithExt.dll_%random%.tmp\"\nif exist \"%tmp%\\PowerToys.FileLocksmithContextMenu.dll_*\" del \"%tmp%\\PowerToys.FileLocksmithContextMenu.dll_*\"\nif exist \"%installpath%WinUI3Apps\\PowerToys.FileLocksmithContextMenu.dll\" move \"%installpath%WinUI3Apps\\PowerToys.FileLocksmithContextMenu.dll\" \"%tmp%\\PowerToys.FileLocksmithContextMenu.dll_%random%.tmp\"\nif exist \"%tmp%\\PowerToys.PowerRenameExt.dll_*\" del \"%tmp%\\PowerToys.PowerRenameExt.dll_*\"\nif exist \"%installpath%WinUI3Apps\\PowerToys.PowerRenameExt.dll\" move \"%installpath%WinUI3Apps\\PowerToys.PowerRenameExt.dll\" \"%tmp%\\PowerToys.PowerRenameExt.dll_%random%.tmp\"\nif exist \"%tmp%\\PowerToys.PowerRenameContextMenu.dll_*\" del \"%tmp%\\PowerToys.PowerRenameContextMenu.dll_*\"\nif exist \"%installpath%WinUI3Apps\\PowerToys.PowerRenameContextMenu.dll\" move \"%installpath%WinUI3Apps\\PowerToys.PowerRenameContextMenu.dll\" \"%tmp%\\PowerToys.PowerRenameContextMenu.dll_%random%.tmp\"\nif exist \"%tmp%\\PowerToys.RegistryPreviewExt.dll_*\" del \"%tmp%\\PowerToys.RegistryPreviewExt.dll_*\"\nif exist \"%installpath%WinUI3Apps\\PowerToys.RegistryPreviewExt.dll\" move \"%installpath%WinUI3Apps\\PowerToys.RegistryPreviewExt.dll\" \"%tmp%\\PowerToys.RegistryPreviewExt.dll_%random%.tmp\"\nif exist \"%tmp%\\PowerToys.ImageResizerExt.dll_*\" del \"%tmp%\\PowerToys.ImageResizerExt.dll_*\"\nif exist \"%installpath%PowerToys.ImageResizerExt.dll\" move \"%installpath%PowerToys.ImageResizerExt.dll\" \"%tmp%\\PowerToys.ImageResizerExt.dll_%random%.tmp\"\necho 再试一次...\necho.\necho.\ncall :killpt\nrmdir /s /q %installpath%WinUI3Apps\\Assets\\NewPlus\\Templates\nxcopy \".\\%softname% %modver%\\*\" \"%installpath%\" /e /y\nif %errorlevel%==0 goto success\necho 尝试解锁...\ntaskkill /f /im explorer.exe\nrmdir /s /q %installpath%WinUI3Apps\\Assets\\NewPlus\\Templates\nxcopy \".\\%softname% %modver%\\*\" \"%installpath%\" /e /y\nif %errorlevel%==0 start explorer&goto success\nstart explorer\necho 安装失败！未能解除文件占用，请尝试手动复制，或重启后再试。\n::\nmsg %username% /time:2 /v /w 安装失败！未能解除文件占用，请尝试手动复制，或重启后再试。>nul\nset /p =请按任意键退出. . . &exit\ngoto :eof\n\n:success\necho 重启文件资源管理器以加载汉化右键菜单\n::\npowershell exit\ntaskkill /f /im explorer.exe>nul 2>nul\ntaskkill /f /im explorer.exe>nul 2>nul\ntaskkill /f /im explorer.exe>nul 2>nul\npowershell exit\nstart explorer\npowershell exit\necho 启动 PowerToys\nmshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"%installpath%PowerToys.exe\",\"\",\"\",\"runas\",1)(window.close)\npowershell exit\necho 打开 PowerToys 设置\nmshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"%installpath%PowerToys.exe\",\"\",\"\",\"runas\",1)(window.close)\npowershell exit\necho 安装完成\n:: Powershell 用于提供一个恰当的启动延迟\n::\nmsg %username% /time:2 /v /w 安装完成！>nul\ngoto :eof\n\n:killpt\ntaskkill /F /IM \"PowerToys*\"\ntaskkill /F /IM \"PowerToys*\"\ngoto :eof"
  },
  {
    "path": "Patcher/安装组策略.cmd",
    "content": "chcp 65001>nul\n@echo off\necho 正在安装 PowerToys 组策略...\n%1 mshta vbscript:CreateObject(\"Shell.Application\").ShellExecute(\"cmd.exe\",\"/c %~s0 ::\",\"\",\"runas\",1)(window.close)&&goto :eOF\ncd /d %~dp0\nxcopy /Y /I /E \".\\PowerToys.admx\" \"%systemroot%\\PolicyDefinitions\\\"\nxcopy /Y /I /E \".\\zh-CN\\PowerToys.adml\" \"%systemroot%\\PolicyDefinitions\\zh-CN\\\"\nxcopy /Y /I /E \".\\en-US\\PowerToys.adml\" \"%systemroot%\\PolicyDefinitions\\en-US\\\"\nmsg %username% 安装完成"
  },
  {
    "path": "PowerToys/global.json",
    "content": "{\n  \"sdk\": {\n    \"allowPrerelease\": false\n  }\n}"
  },
  {
    "path": "PowerToys/src/ActionRunner/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"DOTNET_CORE_DOWNLOAD_FAILURE\" xml:space=\"preserve\">\n    <value>无法下载 .NET Core Desktop Runtime 3.1，请自行安装。</value>\n  </data>\n  <data name=\"DOTNET_CORE_DOWNLOAD_FAILURE_TITLE\" xml:space=\"preserve\">\n    <value>PowerToys 安装错误</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT\" xml:space=\"preserve\">\n    <value>PowerToys 有版本更新。请访问 GitHub 页面下载。</value>\n  </data>\n</root>\n"
  },
  {
    "path": "PowerToys/src/Monaco/index.html",
    "content": "﻿<!doctype HTML>\n<html>\n<head>\n    <script>\n        // Set variables\n\n        // Get URL parameters:\n        // `code` contains the code of the file in base64 encoded\n        // `theme` can be \"vs\" for light theme or \"vs-dark\" for dark theme\n        // `lang` is the language of the file\n        // `wrap` if the editor is wrapping or not\n        // `minimap` if the minimap is shown\n        // `contextMenu` whether to use the Monaco context menu. The built-in context menu\n        //               doesn't work in Peek, so we set this to false and create a custom one\n\n        var theme = (\"[[PT_THEME]]\" == \"dark\") ? \"vs-dark\" : \"vs\";\n        var wrap = [[PT_WRAP]];\n        var minimap = [[PT_MINIMAP]];\n        var stickyScroll = [[PT_STICKY_SCROLL]];\n        var fontSize = [[PT_FONT_SIZE]];\n        \n        var lang = \"[[PT_LANG]]\";\n        var base64code = \"[[PT_CODE]]\";\n        var contextMenu = [[PT_CONTEXTMENU]];\n\n        var editor;\n\n        // Code taken from https://stackoverflow.com/a/30106551/14774889\n        var code = decodeURIComponent(atob(base64code).split('').map(function (c) {\n            return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);\n        }).join(''));\n\n        function runToggleTextWrapCommand() {\n            wrap = !wrap;\n            editor.updateOptions({ wordWrap: wrap ? 'on' : 'off' });\n        }\n\n        function runToggleMinimap() {\n            minimap = !minimap;\n            editor.updateOptions({minimap: {enabled: minimap}});\n        }\n\n        function runCopyCommand() {\n            editor.focus();\n            document.execCommand('copy');\n        }\n\n    </script>\n    <!-- Set browser to Edge-->\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\" />\n    <!-- Set charset -->\n    <meta charset=\"utf-8\" />\n    <!-- Title (normally not displayed)-->\n    <title>Previewer for developer Files</title>\n    <style>\n        /* Fits content to window size */\n        html, body {\n            padding: 0;\n        }\n\n        #container, .monaco-editor {\n            position: fixed;\n            height: 100%;\n            left: 0;\n            top: 0;\n            right: 0;\n            bottom: 0;\n        }\n\n        .overflowingContentWidgets {\n            /*Hides alert box */\n            display: none !important\n        }\n    </style>\n</head>\n\n<body>\n    <!-- Container for the editor -->\n    <div id=\"container\"></div>\n    <!-- Script -->\n    <script src=\"http://[[PT_URL]]/monacoSRC/min/vs/loader.js\"></script>\n    <script src=\"http://[[PT_URL]]/monacoSpecialLanguages.js\" type=\"module\"></script>\n    <script type=\"module\">\n        import { registerAdditionalLanguages } from 'http://[[PT_URL]]/monacoSpecialLanguages.js';\n        import { customTokenThemeRules } from 'http://[[PT_URL]]/customTokenThemeRules.js';\n        require.config({ paths: { vs: 'http://[[PT_URL]]/monacoSRC/min/vs' } });\n        require(['vs/editor/editor.main'], async function () {\n            await registerAdditionalLanguages(monaco)\n\n            // Creates a theme to handle custom tokens\n            monaco.editor.defineTheme('theme', {\n                base: theme, // Sets the base theme to \"vs\" or \"vs-dark\" depending on the user's preference\n                inherit: true,\n                rules: customTokenThemeRules,\n                colors: {} // `colors` is a required attribute\n            });\n\n            // Creates the editor\n            // For all parameters: https://microsoft.github.io/monaco-editor/typedoc/interfaces/editor.IStandaloneEditorConstructionOptions.html\n            editor = monaco.editor.create(document.getElementById('container'), {\n                value: code, // Sets content of the editor\n                language: lang, // Sets language of the code\n                readOnly: true, // Sets to readonly\n                theme: 'theme', // Sets editor theme\n                minimap: { enabled: minimap }, // Controls if minimap is shown\n                lineNumbersMinChars: 3, // Width of the line numbers\n                contextmenu: contextMenu,\n                scrollbar: {\n                    // Deactivate shadows\n                    shadows: false,\n\n                    // Render scrollbar automatically\n                    vertical: 'auto',\n                    horizontal: 'auto',\n                },\n                stickyScroll: { enabled: stickyScroll },\n                fontSize: fontSize,\n                wordWrap: (wrap ? 'on' : 'off') // Word wraps\n            });\n            window.onresize = () => {\n                editor.layout();\n            };\n\n            // Add toggle wrap button to context menu\n            editor.addAction({\n                id: 'text-wrap',\n\n                label: '自动换行',\n\n                // A precondition for this action.\n                precondition: null,\n\n                // A rule to evaluate on top of the precondition in order to dispatch the keybindings.\n                keybindingContext: null,\n\n                contextMenuGroupId: 'cutcopypaste',\n\n                contextMenuOrder: 100,\n\n                // Method that will be executed when the action is triggered.\n                run: runToggleTextWrapCommand\n            });\n\n            editor.addAction({\n                id: 'toggle-minimap',\n\n                label: '小地图',\n\n                contextMenuGroupId: 'cutcopypaste',\n\n                contextMenuOrder: 100,\n\n                // Method that will be executed when the action is triggered.\n                run: runToggleMinimap\n            });\n\n            onContextMenu();\n        });\n\n        function onContextMenu() {\n            // Hide context menu items\n            // Code modified from https://stackoverflow.com/questions/48745208/disable-cut-and-copy-in-context-menu-in-monaco-editor/65413517#65413517\n            let menus = require('vs/platform/actions/common/actions').MenuRegistry._menuItems\n            let contextMenuEntry = [...menus].find(entry => entry[0].id == 'EditorContext')\n            let contextMenuLinks = contextMenuEntry[1]\n\n            let removableIds = ['editor.action.clipboardCutAction', 'editor.action.formatDocument', 'editor.action.formatSelection', 'editor.action.quickCommand', 'editor.action.quickOutline', 'editor.action.refactor', 'editor.action.sourceAction', 'editor.action.rename', undefined, 'editor.action.revealDefinition', 'editor.action.revealDeclaration', 'editor.action.goToTypeDefinition', 'editor.action.goToImplementation', 'editor.action.goToReferences', 'editor.action.changeAll']\n\n            let removeById = (list, ids) => {\n                let node = list._first\n                do {\n                    if (node.element == undefined) break;\n                    let shouldRemove = ids.includes(node.element?.command?.id)\n                    if (shouldRemove) { list._remove(node) }\n                } while ((node = node.next))\n            }\n\n            removeById(contextMenuLinks, removableIds)\n        }\n    </script>\n</body>\n</html>"
  },
  {
    "path": "PowerToys/src/Update/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"DOTNET_CORE_DOWNLOAD_FAILURE\" xml:space=\"preserve\">\n    <value>无法下载 .NET Core Desktop Runtime 3.1，请自行安装。</value>\n  </data>\n  <data name=\"DOTNET_CORE_DOWNLOAD_FAILURE_TITLE\" xml:space=\"preserve\">\n    <value>PowerToys 安装错误</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_AVAILABLE\" xml:space=\"preserve\">\n    <value>PowerToys 有版本更新。</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_UPDATE_NOW\" xml:space=\"preserve\">\n    <value>立刻更新</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT\" xml:space=\"preserve\">\n    <value>PowerToys 有版本更新。请访问 GitHub 页面下载。</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_MORE_INFO\" xml:space=\"preserve\">\n    <value>更多信息</value>\n  </data>\n  <data name=\"TOAST_TITLE\" xml:space=\"preserve\">\n    <value>PowerToys 更新</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/Version.props",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <Version>0.88.0</Version>\n\n    <!-- Forcing for every DLL on by default -->\n    <ChecksumAlgorithm>SHA256</ChecksumAlgorithm>\n  </PropertyGroup>\n</Project>\n"
  },
  {
    "path": "PowerToys/src/common/interop/keyboard_layout.cpp",
    "content": "﻿#include \"pch.h\"\n#include <array>\n#include <algorithm>\n\n#include \"keyboard_layout_impl.h\"\n#include \"shared_constants.h\"\n\nconstexpr DWORD numpadOriginBit = 1ull << 31;\n\nLayoutMap::LayoutMap() :\n    impl(new LayoutMap::LayoutMapImpl())\n{\n}\n\nLayoutMap::~LayoutMap()\n{\n    delete impl;\n}\n\nvoid LayoutMap::UpdateLayout()\n{\n    impl->UpdateLayout();\n}\n\nstd::wstring LayoutMap::GetKeyName(DWORD key)\n{\n    return impl->GetKeyName(key);\n}\n\nDWORD LayoutMap::GetKeyFromName(const std::wstring& name)\n{\n    auto list = impl->GetKeyNameList(false);\n    for (const auto& [value, key] : list)\n    {\n        if (key == name)\n            return value;\n    }\n    return {};\n}\n\nstd::vector<DWORD> LayoutMap::GetKeyCodeList(const bool isShortcut)\n{\n    return impl->GetKeyCodeList(isShortcut);\n}\n\nstd::vector<std::pair<DWORD, std::wstring>> LayoutMap::GetKeyNameList(const bool isShortcut)\n{\n    return impl->GetKeyNameList(isShortcut);\n}\n\n// Function to return the unicode string name of the key\nstd::wstring LayoutMap::LayoutMapImpl::GetKeyName(DWORD key)\n{\n    std::wstring result = L\"未定义\";\n    std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);\n    UpdateLayout();\n\n    auto it = keyboardLayoutMap.find(key);\n    if (it != keyboardLayoutMap.end())\n    {\n        result = it->second;\n    }\n    return result;\n}\n\nbool mapKeycodeToUnicode(const int vCode, HKL layout, const BYTE* keyState, std::array<wchar_t, 3>& outBuffer)\n{\n    // Get the scan code from the virtual key code\n    const UINT scanCode = MapVirtualKeyExW(vCode, MAPVK_VK_TO_VSC, layout);\n    // Get the unicode representation from the virtual key code and scan code pair\n    const UINT wFlags = 1 << 2; // If bit 2 is set, keyboard state is not changed (Windows 10, version 1607 and newer)\n    const int result = ToUnicodeEx(vCode, scanCode, keyState, outBuffer.data(), static_cast<int>(outBuffer.size()), wFlags, layout);\n    return result != 0;\n}\n\n// Update Keyboard layout according to input locale identifier\nvoid LayoutMap::LayoutMapImpl::UpdateLayout()\n{\n    // Get keyboard layout for current thread\n    const HKL layout = GetKeyboardLayout(0);\n    if (layout == previousLayout)\n    {\n        return;\n    }\n    previousLayout = layout;\n    if (!isKeyCodeListGenerated)\n    {\n        unicodeKeys.clear();\n        unknownKeys.clear();\n    }\n\n    std::array<BYTE, 256> btKeys = { 0 };\n    // Only set the Caps Lock key to on for the key names in uppercase\n    btKeys[VK_CAPITAL] = 1;\n\n    // Iterate over all the virtual key codes. virtual key 0 is not used\n    for (int i = 1; i < 256; i++)\n    {\n        std::array<wchar_t, 3> szBuffer = { 0 };\n        if (mapKeycodeToUnicode(i, layout, btKeys.data(), szBuffer))\n        {\n            keyboardLayoutMap[i] = szBuffer.data();\n            if (!isKeyCodeListGenerated)\n            {\n                unicodeKeys[i] = szBuffer.data();\n            }\n            continue;\n        }\n\n        // Store the virtual key code as string\n        std::wstring vk = L\"虚拟键值 \";\n        vk += std::to_wstring(i);\n        keyboardLayoutMap[i] = vk;\n        if (!isKeyCodeListGenerated)\n        {\n            unknownKeys[i] = vk;\n        }\n    }\n\n    // Override special key names like Shift, Ctrl etc because they don't have unicode mappings and key names like Enter, Space as they appear as \"\\r\", \" \"\n    // To do: localization\n    keyboardLayoutMap[VK_CANCEL] = L\"Break\";\n    keyboardLayoutMap[VK_BACK] = L\"Backspace\";\n    keyboardLayoutMap[VK_TAB] = L\"Tab\";\n    keyboardLayoutMap[VK_CLEAR] = L\"Clear\";\n    keyboardLayoutMap[VK_SHIFT] = L\"Shift\";\n    keyboardLayoutMap[VK_CONTROL] = L\"Ctrl\";\n    keyboardLayoutMap[VK_MENU] = L\"Alt\";\n    keyboardLayoutMap[VK_PAUSE] = L\"Pause\";\n    keyboardLayoutMap[VK_CAPITAL] = L\"Caps Lock\";\n    keyboardLayoutMap[VK_ESCAPE] = L\"Esc\";\n    keyboardLayoutMap[VK_SPACE] = L\"Space\";\n\n    keyboardLayoutMap[VK_LEFT] = L\"Left\";\n    keyboardLayoutMap[VK_RIGHT] = L\"Right\";\n    keyboardLayoutMap[VK_UP] = L\"Up\";\n    keyboardLayoutMap[VK_DOWN] = L\"Down\";\n    keyboardLayoutMap[VK_INSERT] = L\"Insert\";\n    keyboardLayoutMap[VK_DELETE] = L\"Delete\";\n    keyboardLayoutMap[VK_PRIOR] = L\"PgUp\";\n    keyboardLayoutMap[VK_NEXT] = L\"PgDn\";\n    keyboardLayoutMap[VK_HOME] = L\"Home\";\n    keyboardLayoutMap[VK_END] = L\"End\";\n    keyboardLayoutMap[VK_RETURN] = L\"Enter\";\n\n    keyboardLayoutMap[VK_LEFT | numpadOriginBit] = L\"Left (小键盘)\";\n    keyboardLayoutMap[VK_RIGHT | numpadOriginBit] = L\"Right (小键盘)\";\n    keyboardLayoutMap[VK_UP | numpadOriginBit] = L\"Up (小键盘)\";\n    keyboardLayoutMap[VK_DOWN | numpadOriginBit] = L\"Down (小键盘)\";\n    keyboardLayoutMap[VK_INSERT | numpadOriginBit] = L\"Insert (小键盘)\";\n    keyboardLayoutMap[VK_DELETE | numpadOriginBit] = L\"Delete (小键盘)\";\n    keyboardLayoutMap[VK_PRIOR | numpadOriginBit] = L\"PgUp (小键盘)\";\n    keyboardLayoutMap[VK_NEXT | numpadOriginBit] = L\"PgDn (小键盘)\";\n    keyboardLayoutMap[VK_HOME | numpadOriginBit] = L\"Home (小键盘)\";\n    keyboardLayoutMap[VK_END | numpadOriginBit] = L\"End (小键盘)\";\n    keyboardLayoutMap[VK_RETURN | numpadOriginBit] = L\"Enter (小键盘)\";\n    keyboardLayoutMap[VK_DIVIDE | numpadOriginBit] = L\"/ (小键盘)\";\n\n    keyboardLayoutMap[VK_SUBTRACT] = L\"- (小键盘)\";\n    keyboardLayoutMap[VK_SELECT] = L\"Select\";\n    keyboardLayoutMap[VK_PRINT] = L\"Print\";\n    keyboardLayoutMap[VK_EXECUTE] = L\"Execute\";\n    keyboardLayoutMap[VK_SNAPSHOT] = L\"Print Screen\";\n    keyboardLayoutMap[VK_HELP] = L\"Help\";\n    keyboardLayoutMap[VK_LWIN] = L\"Win (左)\";\n    keyboardLayoutMap[VK_RWIN] = L\"Win (右)\";\n    keyboardLayoutMap[VK_APPS] = L\"Apps/Menu\";\n    keyboardLayoutMap[VK_SLEEP] = L\"Sleep\";\n    keyboardLayoutMap[VK_NUMPAD0] = L\"0 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD1] = L\"1 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD2] = L\"2 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD3] = L\"3 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD4] = L\"4 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD5] = L\"5 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD6] = L\"6 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD7] = L\"7 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD8] = L\"8 (小键盘)\";\n    keyboardLayoutMap[VK_NUMPAD9] = L\"9 (小键盘)\";\n    keyboardLayoutMap[VK_SEPARATOR] = L\"Separator\";\n    keyboardLayoutMap[VK_F1] = L\"F1\";\n    keyboardLayoutMap[VK_F2] = L\"F2\";\n    keyboardLayoutMap[VK_F3] = L\"F3\";\n    keyboardLayoutMap[VK_F4] = L\"F4\";\n    keyboardLayoutMap[VK_F5] = L\"F5\";\n    keyboardLayoutMap[VK_F6] = L\"F6\";\n    keyboardLayoutMap[VK_F7] = L\"F7\";\n    keyboardLayoutMap[VK_F8] = L\"F8\";\n    keyboardLayoutMap[VK_F9] = L\"F9\";\n    keyboardLayoutMap[VK_F10] = L\"F10\";\n    keyboardLayoutMap[VK_F11] = L\"F11\";\n    keyboardLayoutMap[VK_F12] = L\"F12\";\n    keyboardLayoutMap[VK_F13] = L\"F13\";\n    keyboardLayoutMap[VK_F14] = L\"F14\";\n    keyboardLayoutMap[VK_F15] = L\"F15\";\n    keyboardLayoutMap[VK_F16] = L\"F16\";\n    keyboardLayoutMap[VK_F17] = L\"F17\";\n    keyboardLayoutMap[VK_F18] = L\"F18\";\n    keyboardLayoutMap[VK_F19] = L\"F19\";\n    keyboardLayoutMap[VK_F20] = L\"F20\";\n    keyboardLayoutMap[VK_F21] = L\"F21\";\n    keyboardLayoutMap[VK_F22] = L\"F22\";\n    keyboardLayoutMap[VK_F23] = L\"F23\";\n    keyboardLayoutMap[VK_F24] = L\"F24\";\n    keyboardLayoutMap[VK_NUMLOCK] = L\"Num Lock\";\n    keyboardLayoutMap[VK_SCROLL] = L\"Scroll Lock\";\n    keyboardLayoutMap[VK_LSHIFT] = L\"Shift (左)\";\n    keyboardLayoutMap[VK_RSHIFT] = L\"Shift (右)\";\n    keyboardLayoutMap[VK_LCONTROL] = L\"Ctrl (左)\";\n    keyboardLayoutMap[VK_RCONTROL] = L\"Ctrl (右)\";\n    keyboardLayoutMap[VK_LMENU] = L\"Alt (左)\";\n    keyboardLayoutMap[VK_RMENU] = L\"Alt (右)\";\n    keyboardLayoutMap[VK_BROWSER_BACK] = L\"Browser Back\";\n    keyboardLayoutMap[VK_BROWSER_FORWARD] = L\"Browser Forward\";\n    keyboardLayoutMap[VK_BROWSER_REFRESH] = L\"Browser Refresh\";\n    keyboardLayoutMap[VK_BROWSER_STOP] = L\"Browser Stop\";\n    keyboardLayoutMap[VK_BROWSER_SEARCH] = L\"Browser Search\";\n    keyboardLayoutMap[VK_BROWSER_FAVORITES] = L\"Browser Favorites\";\n    keyboardLayoutMap[VK_BROWSER_HOME] = L\"Browser Home\";\n    keyboardLayoutMap[VK_VOLUME_MUTE] = L\"Volume Mute\";\n    keyboardLayoutMap[VK_VOLUME_DOWN] = L\"Volume Down\";\n    keyboardLayoutMap[VK_VOLUME_UP] = L\"Volume Up\";\n    keyboardLayoutMap[VK_MEDIA_NEXT_TRACK] = L\"Next Track\";\n    keyboardLayoutMap[VK_MEDIA_PREV_TRACK] = L\"Previous Track\";\n    keyboardLayoutMap[VK_MEDIA_STOP] = L\"Stop Media\";\n    keyboardLayoutMap[VK_MEDIA_PLAY_PAUSE] = L\"Play/Pause Media\";\n    keyboardLayoutMap[VK_LAUNCH_MAIL] = L\"Start Mail\";\n    keyboardLayoutMap[VK_LAUNCH_MEDIA_SELECT] = L\"Select Media\";\n    keyboardLayoutMap[VK_LAUNCH_APP1] = L\"Start App 1\";\n    keyboardLayoutMap[VK_LAUNCH_APP2] = L\"Start App 2\";\n    keyboardLayoutMap[VK_PACKET] = L\"Packet\";\n    keyboardLayoutMap[VK_ATTN] = L\"Attn\";\n    keyboardLayoutMap[VK_CRSEL] = L\"CrSel\";\n    keyboardLayoutMap[VK_EXSEL] = L\"ExSel\";\n    keyboardLayoutMap[VK_EREOF] = L\"Erase EOF\";\n    keyboardLayoutMap[VK_PLAY] = L\"Play\";\n    keyboardLayoutMap[VK_ZOOM] = L\"Zoom\";\n    keyboardLayoutMap[VK_PA1] = L\"PA1\";\n    keyboardLayoutMap[VK_OEM_CLEAR] = L\"Clear\";\n    keyboardLayoutMap[0xFF] = L\"未定义\";\n    keyboardLayoutMap[CommonSharedConstants::VK_WIN_BOTH] = L\"Win\";\n    keyboardLayoutMap[VK_KANA] = L\"IME Kana\";\n    keyboardLayoutMap[VK_HANGEUL] = L\"IME Hangeul\";\n    keyboardLayoutMap[VK_HANGUL] = L\"IME Hangul\";\n    keyboardLayoutMap[VK_IME_ON] = L\"IME On\";\n    keyboardLayoutMap[VK_JUNJA] = L\"IME Junja\";\n    keyboardLayoutMap[VK_FINAL] = L\"IME Final\";\n    keyboardLayoutMap[VK_HANJA] = L\"IME Hanja\";\n    keyboardLayoutMap[VK_KANJI] = L\"IME Kanji\";\n    keyboardLayoutMap[VK_IME_OFF] = L\"IME Off\";\n    keyboardLayoutMap[VK_CONVERT] = L\"IME Convert\";\n    keyboardLayoutMap[VK_NONCONVERT] = L\"IME Non-Convert\";\n    keyboardLayoutMap[VK_ACCEPT] = L\"IME Kana\";\n    keyboardLayoutMap[VK_MODECHANGE] = L\"IME Mode Change\";\n    keyboardLayoutMap[VK_DECIMAL] = L\". (小键盘)\";\n    keyboardLayoutMap[CommonSharedConstants::VK_DISABLED] = L\"禁用\";\n}\n\n// Function to return the list of key codes in the order for the drop down. It creates it if it doesn't exist\nstd::vector<DWORD> LayoutMap::LayoutMapImpl::GetKeyCodeList(const bool isShortcut)\n{\n    std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);\n    UpdateLayout();\n    std::vector<DWORD> keyCodes;\n    if (!isKeyCodeListGenerated)\n    {\n        // Add character keys\n        for (auto& it : unicodeKeys)\n        {\n            // If it was not renamed with a special name\n            if (it.second == keyboardLayoutMap[it.first])\n            {\n                keyCodes.push_back(it.first);\n            }\n        }\n\n        // Add modifier keys in alphabetical order\n        keyCodes.push_back(VK_MENU);\n        keyCodes.push_back(VK_LMENU);\n        keyCodes.push_back(VK_RMENU);\n        keyCodes.push_back(VK_CONTROL);\n        keyCodes.push_back(VK_LCONTROL);\n        keyCodes.push_back(VK_RCONTROL);\n        keyCodes.push_back(VK_SHIFT);\n        keyCodes.push_back(VK_LSHIFT);\n        keyCodes.push_back(VK_RSHIFT);\n        keyCodes.push_back(CommonSharedConstants::VK_WIN_BOTH);\n        keyCodes.push_back(VK_LWIN);\n        keyCodes.push_back(VK_RWIN);\n\n        // Add all other special keys\n        std::vector<DWORD> specialKeys;\n        for (int i = 1; i < 256; i++)\n        {\n            // If it is not already been added (i.e. it was either a modifier or had a unicode representation)\n            if (std::find(keyCodes.begin(), keyCodes.end(), i) == keyCodes.end())\n            {\n                // If it is any other key but it is not named as VK #\n                auto it = unknownKeys.find(i);\n                if (it == unknownKeys.end())\n                {\n                    specialKeys.push_back(i);\n                }\n                else if (unknownKeys[i] != keyboardLayoutMap[i])\n                {\n                    specialKeys.push_back(i);\n                }\n            }\n        }\n\n        // Add numpad keys\n        for (auto it = keyboardLayoutMap.rbegin(); it->first & numpadOriginBit; ++it)\n        {\n            keyCodes.push_back(it->first);\n        }\n\n        // Sort the special keys in alphabetical order\n        std::sort(specialKeys.begin(), specialKeys.end(), [&](const DWORD& lhs, const DWORD& rhs) {\n            return keyboardLayoutMap[lhs] < keyboardLayoutMap[rhs];\n        });\n        for (int i = 0; i < specialKeys.size(); i++)\n        {\n            keyCodes.push_back(specialKeys[i]);\n        }\n\n        // Add unknown keys\n        for (auto& it : unknownKeys)\n        {\n            // If it was not renamed with a special name\n            if (it.second == keyboardLayoutMap[it.first])\n            {\n                keyCodes.push_back(it.first);\n            }\n        }\n        keyCodeList = keyCodes;\n        isKeyCodeListGenerated = true;\n    }\n    else\n    {\n        keyCodes = keyCodeList;\n    }\n\n    // If it is a key list for the shortcut control then we add a \"None\" key at the start\n    if (isShortcut)\n    {\n        keyCodes.insert(keyCodes.begin(), 0);\n    }\n\n    return keyCodes;\n}\n\nstd::vector<std::pair<DWORD, std::wstring>> LayoutMap::LayoutMapImpl::GetKeyNameList(const bool isShortcut)\n{\n    std::vector<std::pair<DWORD, std::wstring>> keyNames;\n    std::vector<DWORD> keyCodes = GetKeyCodeList(isShortcut);\n    std::lock_guard<std::mutex> lock(keyboardLayoutMap_mutex);\n    // If it is a key list for the shortcut control then we add a \"None\" key at the start\n    if (isShortcut)\n    {\n        keyNames.push_back({ 0, L\"无\" });\n        for (int i = 1; i < keyCodes.size(); i++)\n        {\n            keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] });\n        }\n    }\n    else\n    {\n        for (int i = 0; i < keyCodes.size(); i++)\n        {\n            keyNames.push_back({ keyCodes[i], keyboardLayoutMap[keyCodes[i]] });\n        }\n    }\n\n    return keyNames;\n}\n"
  },
  {
    "path": "PowerToys/src/common/sysinternals/Eula/eula.c",
    "content": "﻿#pragma once\n\n#pragma warning( disable: 4996) \n\n#include <windows.h>\n#include <stdio.h>\n#include <tchar.h>\n#include <Richedit.h>\n#include <conio.h>\n#include <fcntl.h>\n#include <io.h>\n#include \"Eula.h\"\n#include \"dll.h\"\n\n#define\tIDC_TEXT\t500\n#define IDC_PRINT\t501\n#define\tIDC_TEXT1\t502\n\nstatic const char * EulaText[] = {\n\"{\\\\rtf1\\\\ansi\\\\ansicpg1252\\\\deff0\\\\nouicompat\\\\deflang1033{\\\\fonttbl{\\\\f0\\\\fswiss\\\\fprq2\\\\fcharset0 Tahoma;}{\\\\f1\\\\fnil\\\\fcharset0 Calibri;}}\",\n\"{\\\\colortbl ;\\\\red0\\\\green0\\\\blue255;\\\\red0\\\\green0\\\\blue0;}\",\n\"{\\\\*\\\\generator Riched20 10.0.10240}\\\\viewkind4\\\\uc1 \",\n\"\\\\pard\\\\brdrb\\\\brdrs\\\\brdrw10\\\\brsp20 \\\\sb120\\\\sa120\\\\b\\\\f0\\\\fs24 SYSINTERNALS SOFTWARE LICENSE TERMS\\\\fs28\\\\par\",\n\"\\\\pard\\\\sb120\\\\sa120\\\\b0\\\\fs19 These license terms are an agreement between Sysinternals (a wholly owned subsidiary of Microsoft Corporation) and you.  Please read them.  They apply to the software you are downloading from Sysinternals.com, which includes the media on which you received it, if any.  The terms also apply to any Sysinternals\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\tx720\\\\'b7\\\\tab updates,\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\'b7\\\\tab supplements,\\\\par\",\n\"\\\\'b7\\\\tab Internet-based services, and \\\\par\",\n\"\\\\'b7\\\\tab support services\\\\par\",\n\"\\\\pard\\\\sb120\\\\sa120 for this software, unless other terms accompany those items.  If so, those terms apply.\\\\par\",\n\"\\\\b BY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.  IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\\\\par\",\n\"\\\\pard\\\\brdrt\\\\brdrs\\\\brdrw10\\\\brsp20 \\\\sb120\\\\sa120 If you comply with these license terms, you have the rights below.\\\\par\",\n\"\\\\pard\\\\fi-357\\\\li357\\\\sb120\\\\sa120\\\\tx360\\\\fs20 1.\\\\tab\\\\fs19 INSTALLATION AND USE RIGHTS.  \\\\b0 You may install and use any number of copies of the software on your devices.\\\\b\\\\par\",\n\"\\\\caps\\\\fs20 2.\\\\tab\\\\fs19 Scope of License\\\\caps0 .\\\\b0   The software is licensed, not sold. This agreement only gives you some rights to use the software.  Sysinternals reserves all other rights.  Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement.  In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways.    You may not\\\\b\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\tx720\\\\b0\\\\'b7\\\\tab work around any technical limitations in the binary versions of the software;\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\'b7\\\\tab reverse engineer, decompile or disassemble the binary versions of the software, except and only to the extent that applicable law expressly permits, despite this limitation;\\\\par\",\n\"\\\\'b7\\\\tab make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\\\\par\",\n\"\\\\'b7\\\\tab publish the software for others to copy;\\\\par\",\n\"\\\\'b7\\\\tab rent, lease or lend the software;\\\\par\",\n\"\\\\'b7\\\\tab transfer the software or this agreement to any third party; or\\\\par\",\n\"\\\\'b7\\\\tab use the software for commercial software hosting services.\\\\par\",\n\"\\\\pard\\\\fi-357\\\\li357\\\\sb120\\\\sa120\\\\tx360\\\\b\\\\fs20 3.\\\\tab SENSITIVE INFORMATION. \\\\b0  Please be aware that, similar to other debug tools that capture \\\\ldblquote process state\\\\rdblquote  information, files saved by Sysinternals tools may include personally identifiable or other sensitive information (such as usernames, passwords, paths to files accessed, and paths to registry accessed). By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software.\\\\b\\\\par\",\n\"5. \\\\tab\\\\fs19 DOCUMENTATION.\\\\b0   Any person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\\\\b\\\\par\",\n\"\\\\caps\\\\fs20 6.\\\\tab\\\\fs19 Export Restrictions\\\\caps0 .\\\\b0   The software is subject to United States export laws and regulations.  You must comply with all domestic and international export laws and regulations that apply to the software.  These laws include restrictions on destinations, end users and end use.  For additional information, see {\\\\cf1\\\\ul{\\\\field{\\\\*\\\\fldinst{HYPERLINK www.microsoft.com/exporting }}{\\\\fldrslt{www.microsoft.com/exporting}}}}\\\\cf1\\\\ul\\\\f0\\\\fs19  <{{\\\\field{\\\\*\\\\fldinst{HYPERLINK \\\"http://www.microsoft.com/exporting\\\"}}{\\\\fldrslt{http://www.microsoft.com/exporting}}}}\\\\f0\\\\fs19 >\\\\cf0\\\\ulnone .\\\\b\\\\par\",\n\"\\\\caps\\\\fs20 7.\\\\tab\\\\fs19 SUPPORT SERVICES.\\\\caps0  \\\\b0 Because this software is \\\"as is, \\\" we may not provide support services for it.\\\\b\\\\par\",\n\"\\\\caps\\\\fs20 8.\\\\tab\\\\fs19 Entire Agreement.\\\\b0\\\\caps0   This agreement, and the terms for supplements, updates, Internet-based services and support services that you use, are the entire agreement for the software and support services.\\\\par\",\n\"\\\\pard\\\\keepn\\\\fi-360\\\\li360\\\\sb120\\\\sa120\\\\tx360\\\\cf2\\\\b\\\\caps\\\\fs20 9.\\\\tab\\\\fs19 Applicable Law\\\\caps0 .\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\tx720\\\\cf0\\\\fs20 a.\\\\tab\\\\fs19 United States.\\\\b0   If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles.  The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\\\\b\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\fs20 b.\\\\tab\\\\fs19 Outside the United States.\\\\b0   If you acquired the software in any other country, the laws of that country apply.\\\\b\\\\par\",\n\"\\\\pard\\\\fi-357\\\\li357\\\\sb120\\\\sa120\\\\tx360\\\\caps\\\\fs20 10.\\\\tab\\\\fs19 Legal Effect.\\\\b0\\\\caps0   This agreement describes certain legal rights.  You may have other rights under the laws of your country.  You may also have rights with respect to the party from whom you acquired the software.  This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\\\\b\\\\caps\\\\par\",\n\"\\\\fs20 11.\\\\tab\\\\fs19 Disclaimer of Warranty.\\\\caps0    \\\\caps The software is licensed \\\"as - is.\\\"  You bear the risk of using it.  SYSINTERNALS gives no express warranties, guarantees or conditions.  You may have additional consumer rights under your local laws which this agreement cannot change.  To the extent permitted under your local laws, SYSINTERNALS excludes the implied warranties of merchantability, fitness for a particular purpose and non-infringement.\\\\par\",\n\"\\\\pard\\\\fi-360\\\\li360\\\\sb120\\\\sa120\\\\tx360\\\\fs20 12.\\\\tab\\\\fs19 Limitation on and Exclusion of Remedies and Damages.  You can recover from SYSINTERNALS and its suppliers only direct damages up to U.S. $5.00.  You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\\\\par\",\n\"\\\\pard\\\\li357\\\\sb120\\\\sa120\\\\b0\\\\caps0 This limitation applies to\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\tx720\\\\'b7\\\\tab anything related to the software, services, content (including code) on third party Internet sites, or third party programs; and\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\'b7\\\\tab claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\\\\par\",\n\"\\\\pard\\\\li360\\\\sb120\\\\sa120 It also applies even if Sysinternals knew or should have known about the possibility of the damages.  The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\\\\par\",\n\"\\\\pard\\\\b Please note: As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\\\\par\",\n\"\\\\pard\\\\sb240\\\\lang1036 Remarque : Ce logiciel \\\\'e9tant distribu\\\\'e9 au Qu\\\\'e9bec, Canada, certaines des clauses dans ce contrat sont fournies ci-dessous en fran\\\\'e7ais.\\\\par\",\n\"\\\\pard\\\\sb120\\\\sa120 EXON\\\\'c9RATION DE GARANTIE.\\\\b0  Le logiciel vis\\\\'e9 par une licence est offert \\\\'ab tel quel \\\\'bb. Toute utilisation de ce logiciel est \\\\'e0 votre seule risque et p\\\\'e9ril. Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez b\\\\'e9n\\\\'e9ficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualit\\\\'e9 marchande, d'ad\\\\'e9quation \\\\'e0 un usage particulier et d'absence de contrefa\\\\'e7on sont exclues.\\\\par\",\n\"\\\\pard\\\\keepn\\\\sb120\\\\sa120\\\\b LIMITATION DES DOMMAGES-INT\\\\'c9R\\\\'caTS ET EXCLUSION DE RESPONSABILIT\\\\'c9 POUR LES DOMMAGES.\\\\b0   Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement \\\\'e0 hauteur de 5,00 $ US. Vous ne pouvez pr\\\\'e9tendre \\\\'e0 aucune indemnisation pour les autres dommages, y compris les dommages sp\\\\'e9ciaux, indirects ou accessoires et pertes de b\\\\'e9n\\\\'e9fices.\\\\par\",\n\"\\\\lang1033 Cette limitation concerne :\\\\par\",\n\"\\\\pard\\\\keepn\\\\fi-360\\\\li720\\\\sb120\\\\sa120\\\\tx720\\\\lang1036\\\\'b7\\\\tab tout  ce qui est reli\\\\'e9 au logiciel, aux services ou au contenu (y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers ; et\\\\par\",\n\"\\\\pard\\\\fi-363\\\\li720\\\\sb120\\\\sa120\\\\tx720\\\\'b7\\\\tab les r\\\\'e9clamations au titre de violation de contrat ou de garantie, ou au titre de responsabilit\\\\'e9 stricte, de n\\\\'e9gligence ou d'une autre faute dans la limite autoris\\\\'e9e par la loi en vigueur.\\\\par\",\n\"\\\\pard\\\\sb120\\\\sa120 Elle s'applique \\\\'e9galement, m\\\\'eame si Sysinternals connaissait ou devrait conna\\\\'eetre l'\\\\'e9ventualit\\\\'e9 d'un tel dommage.  Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilit\\\\'e9 pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci-dessus ne s'appliquera pas \\\\'e0 votre \\\\'e9gard.\\\\par\",\n\"\\\\b EFFET JURIDIQUE.\\\\b0   Le pr\\\\'e9sent contrat d\\\\'e9crit certains droits juridiques. Vous pourriez avoir d'autres droits pr\\\\'e9vus par les lois de votre pays.  Le pr\\\\'e9sent contrat ne modifie pas les droits que vous conf\\\\'e8rent les lois de votre pays si celles-ci ne le permettent pas.\\\\b\\\\par\",\n\"\\\\pard\\\\b0\\\\fs20\\\\lang1033\\\\par\",\n\"\\\\pard\\\\sa200\\\\sl276\\\\slmult1\\\\f1\\\\fs22\\\\lang9\\\\par\",\n\"}\",\nNULL\n};\n \nstatic const wchar_t *Raw_EulaText = L\"SYSINTERNALS SOFTWARE LICENSE TERMS\\nThese license terms are an agreement between Sysinternals(a wholly owned subsidiary of Microsoft Corporation) and you.Please read them.They apply to the software you are downloading from technet.microsoft.com / sysinternals, which includes the media on which you received it, if any.The terms also apply to any Sysinternals\\n* updates,\\n*supplements,\\n*Internet - based services,\\n*and support services\\nfor this software, unless other terms accompany those items.If so, those terms apply.\\nBY USING THE SOFTWARE, YOU ACCEPT THESE TERMS.IF YOU DO NOT ACCEPT THEM, DO NOT USE THE SOFTWARE.\\n\\nIf you comply with these license terms, you have the rights below.\\nINSTALLATION AND USER RIGHTS\\nYou may install and use any number of copies of the software on your devices.\\n\\nSCOPE OF LICENSE\\nThe software is licensed, not sold.This agreement only gives you some rights to use the software.Sysinternals reserves all other rights.Unless applicable law gives you more rights despite this limitation, you may use the software only as expressly permitted in this agreement.In doing so, you must comply with any technical limitations in the software that only allow you to use it in certain ways.You may not\\n* work around any technical limitations in the software;\\n*reverse engineer, decompile or disassemble the software, except and only to the extent that applicable law expressly permits, despite this limitation;\\n*make more copies of the software than specified in this agreement or allowed by applicable law, despite this limitation;\\n*publish the software for others to copy;\\n*rent, lease or lend the software;\\n*transfer the software or this agreement to any third party; or\\n* use the software for commercial software hosting services.\\n\\nSENSITIVE INFORMATION\\nPlease be aware that, similar to other debug tools that capture “process state” information, files saved by Sysinternals tools may include personally identifiable or other sensitive information(such as usernames, passwords, paths to files accessed, and paths to registry accessed).By using this software, you acknowledge that you are aware of this and take sole responsibility for any personally identifiable or other sensitive information provided to Microsoft or any other party through your use of the software.\\n\\nDOCUMENTATION\\nAny person that has valid access to your computer or internal network may copy and use the documentation for your internal, reference purposes.\\n\\nEXPORT RESTRICTIONS\\nThe software is subject to United States export laws and regulations.You must comply with all domestic and international export laws and regulations that apply to the software.These laws include restrictions on destinations, end users and end use.For additional information, see www.microsoft.com / exporting .\\n\\nSUPPORT SERVICES\\nBecause this software is \\\"as is, \\\" we may not provide support services for it.\\n\\nENTIRE AGREEMENT\\nThis agreement, and the terms for supplements, updates, Internet - based services and support services that you use, are the entire agreement for the software and support services.\\n\\nAPPLICABLE LAW\\nUnited States.If you acquired the software in the United States, Washington state law governs the interpretation of this agreement and applies to claims for breach of it, regardless of conflict of laws principles.The laws of the state where you live govern all other claims, including claims under state consumer protection laws, unfair competition laws, and in tort.\\nOutside the United States.If you acquired the software in any other country, the laws of that country apply.\\n\\nLEGAL EFFECT\\nThis agreement describes certain legal rights.You may have other rights under the laws of your country.You may also have rights with respect to the party from whom you acquired the software.This agreement does not change your rights under the laws of your country if the laws of your country do not permit it to do so.\\n\\nDISCLAIMER OF WARRANTY\\nThe software is licensed \\\"as - is.\\\" You bear the risk of using it.Sysinternals gives no express warranties, guarantees or conditions.You may have additional consumer rights under your local laws which this agreement cannot change.To the extent permitted under your local laws, sysinternals excludes the implied warranties of merchantability, fitness for a particular purpose and non - infringement.\\n\\nLIMITATION ON AND EXCLUSION OF REMEDIES AND DAMAGES\\nYou can recover from sysinternals and its suppliers only direct damages up to U.S.$5.00.You cannot recover any other damages, including consequential, lost profits, special, indirect or incidental damages.\\nThis limitation applies to\\n* anything related to the software, services, content(including code) on third party Internet sites, or third party programs; and\\n* claims for breach of contract, breach of warranty, guarantee or condition, strict liability, negligence, or other tort to the extent permitted by applicable law.\\nIt also applies even if Sysinternals knew or should have known about the possibility of the damages.The above limitation or exclusion may not apply to you because your country may not allow the exclusion or limitation of incidental, consequential or other damages.\\nPlease note : As this software is distributed in Quebec, Canada, some of the clauses in this agreement are provided below in French.\\nRemarque : Ce logiciel étant distribué au Québec, Canada, certaines des clauses dans ce contrat sont fournies ci - dessous en français.\\n\t\t   EXONÉRATION DE GARANTIE.Le logiciel visé par une licence est offert « tel quel ».Toute utilisation de ce logiciel est à votre seule risque et péril.Sysinternals n'accorde aucune autre garantie expresse. Vous pouvez bénéficier de droits additionnels en vertu du droit local sur la protection dues consommateurs, que ce contrat ne peut modifier. La ou elles sont permises par le droit locale, les garanties implicites de qualité marchande, d'adéquation à un usage particulier et d'absence de contrefaçon sont exclues.\\n\t\t   LIMITATION DES DOMMAGES - INTÉRÊTS ET EXCLUSION DE RESPONSABILITÉ POUR LES DOMMAGES.Vous pouvez obtenir de Sysinternals et de ses fournisseurs une indemnisation en cas de dommages directs uniquement à hauteur de 5, 00 $ US.Vous ne pouvez prétendre à aucune indemnisation pour les autres dommages, y compris les dommages spéciaux, indirects ou accessoires et pertes de bénéfices.\\n\\n\t\t   Cette limitation concerne :\\ntout ce qui est relié au logiciel, aux services ou au contenu(y compris le code) figurant sur des sites Internet tiers ou dans des programmes tiers; et\\nles réclamations au titre de violation de contrat ou de garantie, ou au titre de responsabilité stricte, de négligence ou d'une autre faute dans la limite autorisée par la loi en vigueur.\\n\\nElle s'applique également, même si Sysinternals connaissait ou devrait connaître l'éventualité d'un tel dommage. Si votre pays n'autorise pas l'exclusion ou la limitation de responsabilité pour les dommages indirects, accessoires ou de quelque nature que ce soit, il se peut que la limitation ou l'exclusion ci - dessus ne s'appliquera pas à votre égard.\\nEFFET JURIDIQUE.Le présent contrat décrit certains droits juridiques.Vous pourriez avoir d'autres droits prévus par les lois de votre pays. Le présent contrat ne modifie pas les droits que vous confèrent les lois de votre pays si celles-ci ne le permettent pas.\\n\\n\";\n\nBOOL IsEulaRegkeyAdded(const TCHAR * ToolName);\n\nstatic BOOL EulaCenter( HWND hwndChild, HWND hwndParent )\n{\n    RECT    rcChild, rcParent;\n    int     cxChild, cyChild, cxParent, cyParent;\n    int     cxScreen, cyScreen, xNew, yNew;\n    HDC     hdc;\n\n    // Get the Height and Width of the child window\n    GetWindowRect(hwndChild, &rcChild);\n    cxChild = rcChild.right - rcChild.left;\n    cyChild = rcChild.bottom - rcChild.top;\n\n    // Get the Height and Width of the parent window\n    GetWindowRect(hwndParent, &rcParent);\n    cxParent = rcParent.right - rcParent.left;\n    cyParent = rcParent.bottom - rcParent.top;\n\n    // Get the display limits\n    hdc = GetDC(hwndChild);\n    cxScreen = GetDeviceCaps(hdc, HORZRES);\n    cyScreen = GetDeviceCaps(hdc, VERTRES);\n    ReleaseDC(hwndChild, hdc);\n\n    // Calculate new X position, then adjust for screen\n    xNew = rcParent.left + ((cxParent - cxChild) / 2);\n    if (xNew < 0)\n    {\n        xNew = 0;\n    }\n    else if ((xNew + cxChild) > cxScreen)\n    {\n        xNew = cxScreen - cxChild;\n    }\n\n    // Calculate new Y position, then adjust for screen\n    yNew = rcParent.top  + ((cyParent - cyChild) / 2);\n    if (yNew < 0)\n    {\n        yNew = 0;\n    }\n    else if ((yNew + cyChild) > cyScreen)\n    {\n        yNew = cyScreen - cyChild;\n    }\n\n    // Set it, and return\n    return SetWindowPos(hwndChild,\n                        NULL,\n                        xNew, yNew,\n                        0, 0,\n                        SWP_NOSIZE | SWP_NOZORDER);\n}\n\n\n\nstatic BOOL PrintRichedit( HWND hRichedit )\n{\n    // Get the printer.\n    PRINTDLG\tpd = { 0 };\n\n    pd.lStructSize\t= sizeof pd;\n    pd.hwndOwner\t= hRichedit;\n    pd.hInstance\t= GetModuleHandle(NULL);\n    pd.Flags\t\t= PD_RETURNDC | PD_NOPAGENUMS | PD_NOSELECTION | PD_PRINTSETUP;\n    if ( !PrintDlg( &pd ) )  \n        return FALSE;\n\n    {\n        HCURSOR\t\toldCursor\t= SetCursor( LoadCursor( NULL, IDC_WAIT ) );\n        int         nHorzRes\t= GetDeviceCaps( pd.hDC, HORZRES );\n        int\t\t\tnVertRes\t= GetDeviceCaps( pd.hDC, VERTRES );\n        int\t\t\tnLogPixelsX = GetDeviceCaps( pd.hDC, LOGPIXELSX );\n        int\t\t\tnLogPixelsY = GetDeviceCaps( pd.hDC, LOGPIXELSY );\n        FORMATRANGE fr = { 0 };\n        DOCINFO\t\tdi = { 0 };\n        int\t\t\tTotalLength;\n        \n        // Ensure the printer DC is in MM_TEXT mode.\n        SetMapMode( pd.hDC, MM_TEXT );\n        \n        // Rendering to the same DC we are measuring.\n        fr.hdc\t\t\t= pd.hDC;\n        fr.hdcTarget\t= pd.hDC;\n        \n        // Set up the page.\n        fr.rcPage.top\t\t= 0;\n        fr.rcPage.left\t\t= 0;\n        fr.rcPage.bottom\t= (nVertRes/nLogPixelsY) * 1440;\n        fr.rcPage.right\t\t= (nHorzRes/nLogPixelsX) * 1440;\n        \n        // Set up 1\" margins all around.\n        fr.rc = fr.rcPage;\n        InflateRect( &fr.rc, -1440, -1440 );\n        \n        // Default the range of text to print as the entire document.\n        fr.chrg.cpMin = 0;\n        fr.chrg.cpMax = -1;\n        \n        // Set up the print job (standard printing stuff here).\n        di.cbSize = sizeof di;\n        di.lpszDocName = _T(\"Sysinternals License\");\n        \n        // Start the document.\n        StartDoc( pd.hDC, &di );\n        \n        // Find out real size of document in characters.\n        TotalLength = (int) SendMessage ( hRichedit, WM_GETTEXTLENGTH, 0, 0 );\n        for (;;)  {\n            int NextPage;\n\n            // Start the page.\n            StartPage( pd.hDC );\n            \n            // Print as much text as can fit on a page. The return value is\n            // the index of the first character on the next page. \n            NextPage = (int) SendMessage( hRichedit, EM_FORMATRANGE, TRUE, (LPARAM)&fr );\n            \n            // Print last page.\n            EndPage( pd.hDC );\n            \n            if ( NextPage >= TotalLength )\n                break;\n\n            // Adjust the range of characters to start printing at the first character of the next page.\n            fr.chrg.cpMin = NextPage;\n            fr.chrg.cpMax = -1;\n        }\n\n        // Tell the control to release cached information.\n        SendMessage( hRichedit, EM_FORMATRANGE, 0, (LPARAM)NULL );\n        EndDoc( pd.hDC );\n\n        SetCursor( oldCursor );\n    }\n\n    return TRUE;\n} \n\n// combine all text strings into a single string\nchar * GetEulaText()\n{\n    char\t*\ttext;\n    DWORD\t\tlen = 1;\n    int\t\t\ti;\n    for ( i = 0; EulaText[i]; ++i )\n        len += (DWORD) strlen( EulaText[i] );\n    text = (char *) malloc( len );\n    len = 0;\n    for ( i = 0; EulaText[i]; ++i )  {\n        strcpy( text+len, EulaText[i] );\n        len += (DWORD) strlen( EulaText[i] );\n    }\n    text[len] = 0; \n    return text;\n}\n\nDWORD CALLBACK StreamCallback( DWORD_PTR dwCookie, LPBYTE pbBuff, LONG cb, LONG * pcb )\n{\n    const char\t**\tptr = (const char **) dwCookie;\n    LONG_PTR\t\tlen = strlen(*ptr);\n    if ( cb > len )\n        cb = (int) len;\n    memcpy( pbBuff, *ptr, cb );\n    *pcb = cb;\n    *ptr += cb;\n    return 0;\n}\n\nstatic INT_PTR CALLBACK EulaProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )\n{\n    switch ( uMsg ) {\n    case WM_INITDIALOG:\n        {\n            TCHAR\t\ttitle[MAX_PATH];\n            char\t*\ttext = GetEulaText();\n            char\t*\ttextptr = text;\n            EDITSTREAM\tstream = { 0, 0, StreamCallback };\n            stream.dwCookie = (DWORD_PTR) &textptr;\n            _stprintf_s( title, MAX_PATH, _T(\"%s 许可协议\"), (TCHAR *) lParam );\n            SetWindowText( hwndDlg, title );\n            \n            // enter RTF into edit box\n            SendMessage( GetDlgItem(hwndDlg,IDC_TEXT), EM_EXLIMITTEXT, 0, 1024*1024 );\n            SendMessage( GetDlgItem(hwndDlg,IDC_TEXT), EM_STREAMIN, SF_RTF, (LPARAM)&stream );\n            free( text );\n        }\n        return TRUE;\n\n    case WM_CTLCOLORSTATIC:\n        // force background of read-only text window to be white\n        if ( (HWND)lParam == GetDlgItem( hwndDlg, IDC_TEXT)  )  {\n            return (INT_PTR)GetSysColorBrush( COLOR_WINDOW );\n        }\n        break;\n\n    case WM_COMMAND:\n        switch( LOWORD( wParam )) {\n        case IDOK:\n            EndDialog( hwndDlg, TRUE );\n            return TRUE;\n        case IDCANCEL:\n            EndDialog( hwndDlg, FALSE );\n            return TRUE;\n        case IDC_PRINT:\n            PrintRichedit( GetDlgItem(hwndDlg,IDC_TEXT) );\n            return TRUE;\n        }\n        break;\n    }\n    return FALSE;\n}\n\n\nstatic WORD * Align2( WORD * pos )\n{\n    return (WORD *)(((DWORD_PTR)pos + 1) & ~((DWORD_PTR) 1));\n}\nstatic WORD * Align4( WORD * pos )\n{\n    return (WORD *)(((DWORD_PTR)pos + 3) & ~((DWORD_PTR) 3));\n}\n\nstatic int CopyText( WORD * pos, const WCHAR * text )\n{\n    int len = (int) wcslen( text ) + 1;\n    wcscpy( (PWCHAR) pos, text );\n    return len;\n}\n\nBOOL ShowEulaInternal( const TCHAR * ToolName, DWORD eulaAccepted )\n{\n#if !defined(SYSMON_SHARED)\n    HKEY\t\thKey = NULL;\n    TCHAR\t\tkeyName[MAX_PATH];\n\n    _stprintf_s( keyName, MAX_PATH, _T(\"Software\\\\Sysinternals\\\\%s\"), ToolName );\n\n    //\n    // check the regkey value if no -accepteula switch append\n    //\n    if (!eulaAccepted)\n    {\n        eulaAccepted = IsEulaRegkeyAdded(ToolName);\n    }\n#endif\n\n    if( !eulaAccepted ) {\n        if (IsIoTEdition())\n        {\n            eulaAccepted = ShowEulaConsole();\t// display Eula to console and prompt for Eula Accepted.\n            {\n            }\n        }\n        else if (IsRemoteOnlyEdition() || IsRunningRemotely()) // Nano and in remote session will not be able to accept eula from prompt\n        {\n            ShowEulaConsoleNoPrompt();\n        }\n        else\n        {\n            DLGTEMPLATE\t\t*\tdlg = (DLGTEMPLATE\t*)LocalAlloc(LPTR, 1000);\n            WORD\t\t\t*\textra = (WORD *)(dlg + 1);\n            DLGITEMTEMPLATE\t*\titem;\n\n#if defined(SYSMON_SHARED)\n            printf( \"正在打开 EULA 许可协议对话框 ... (使用 -accepteula 可跳过)。\\n\" );\n#endif\n\n            LoadLibrarySafe(_T(\"Riched32.dll\"), DLL_LOAD_LOCATION_SYSTEM );\t// Richedit 1.0 library\n\n            // header\n            dlg->style = DS_MODALFRAME | DS_CENTER | DS_SETFONT | WS_POPUP | WS_CAPTION | WS_SYSMENU | DS_NOFAILCREATE;\n            dlg->x = 0;\n            dlg->y = 0;\n            dlg->cx = 312;\n            dlg->cy = 180;\n            dlg->cdit = 0;\t// number of controls\n\n            *extra++ = 0;\t// menu\n            *extra++ = 0;\t// class\n            extra += CopyText(extra, L\"许可协议\");\n            *extra++ = 8;\t// font size\n            extra += CopyText(extra, L\"MS Shell Dlg\");\n\n            // Command-line message\n            item = (DLGITEMTEMPLATE *)Align4(extra);\n            item->x = 7;\n            item->y = 3;\n            item->cx = 298;\n            item->cy = 14;\n            item->id = IDC_TEXT1;\n            item->style = WS_CHILD | WS_VISIBLE;\n            extra = (WORD *)(item + 1);\n            *extra++ = 0xFFFF;\t// class is ordinal\n            *extra++ = 0x0082;\t// class is static\n            extra += CopyText(extra, L\"您也可使用 /accepteula 命令行开关来同意 EULA。\");\n            *extra++ = 0;\t\t// creation data\n            dlg->cdit++;\n\n            // Agree button\n            item = (DLGITEMTEMPLATE *)Align4(extra);\n            item->x = 201;\n            item->y = 159;\n            item->cx = 50;\n            item->cy = 14;\n            item->id = IDOK;\n            item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP; // | WS_DEFAULT;\n            extra = (WORD *)(item + 1);\n            *extra++ = 0xFFFF;\t// class is ordinal\n            *extra++ = 0x0080;\t// class is button\n            extra += CopyText(extra, L\"同意(&A)\");\n            *extra++ = 0;\t\t// creation data\n            dlg->cdit++;\n\n            // Decline button\n            item = (DLGITEMTEMPLATE *)Align4(extra);\n            item->x = 255;\n            item->y = 159;\n            item->cx = 50;\n            item->cy = 14;\n            item->id = IDCANCEL;\n            item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;\n            extra = (WORD *)(item + 1);\n            *extra++ = 0xFFFF;\t// class is ordinal\n            *extra++ = 0x0080;\t// class is button\n            extra += CopyText(extra, L\"拒绝(&D)\");\n            *extra++ = 0;\t\t// creation data\n            dlg->cdit++;\n\n            // Print button\n            item = (DLGITEMTEMPLATE *)Align4(extra);\n            item->x = 7;\n            item->y = 159;\n            item->cx = 50;\n            item->cy = 14;\n            item->id = IDC_PRINT;\n            item->style = BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP;\n            extra = (WORD *)(item + 1);\n            *extra++ = 0xFFFF;\t// class is ordinal\n            *extra++ = 0x0080;\t// class is button\n            extra += CopyText(extra, L\"打印(&P)\");\n            *extra++ = 0;\t\t// creation data\n            dlg->cdit++;\n\n            // Edit box\n            item = (DLGITEMTEMPLATE *)Align4(extra);\n            item->x = 7;\n            item->y = 14;\n            item->cx = 298;\n            item->cy = 140;\n            item->id = IDC_TEXT;\n            item->style = WS_BORDER | ES_MULTILINE | ES_AUTOVSCROLL | ES_WANTRETURN | WS_VSCROLL | ES_READONLY | WS_CHILD | WS_VISIBLE | WS_TABSTOP;\n            extra = (WORD *)(item + 1);\n            extra += CopyText(extra, L\"RICHEDIT\");\n            extra += CopyText(extra, L\"拒绝(&D)\");\n            *extra++ = 0;\t\t// creation data\n            dlg->cdit++;\n\n            eulaAccepted = (DWORD)DialogBoxIndirectParam(NULL, dlg, NULL, EulaProc, (LPARAM)ToolName);\n            LocalFree(dlg);\n        }\n    }\n#if !defined(SYSMON_SHARED)\n    if ( eulaAccepted ) {\n        if (RegCreateKey(HKEY_CURRENT_USER, keyName, &hKey) == ERROR_SUCCESS) {\n            RegSetValueEx(hKey, _T(\"EulaAccepted\"), 0, REG_DWORD, (BYTE *)&eulaAccepted, sizeof(eulaAccepted));\n            RegCloseKey(hKey);\n        }\n    }\n#endif\n\n    return eulaAccepted != 0;\n}\n\nBOOL ShowEulaW( const TCHAR * ToolName, int *argc, PWCHAR argv[] )\n{\n    DWORD\t\teulaAccepted = 0;\n    int\t\t\ti;\n\n    if ( argc == NULL  ||  argv == NULL )  {\n        typedef LPWSTR * (WINAPI * type_CommandLineToArgvW)( LPCWSTR lpCmdLine, int *pNumArgs );\n        type_CommandLineToArgvW pCommandLineToArgvW = (type_CommandLineToArgvW) GetProcAddress( LoadLibrarySafe(_T(\"Shell32.dll\"), DLL_LOAD_LOCATION_SYSTEM), \"CommandLineToArgvW\" );\n        if ( pCommandLineToArgvW )  {\n            static int argc2;\n            argc = &argc2;\n            argv = (*pCommandLineToArgvW)( GetCommandLineW(), argc );\n        } else {\n            argc = NULL;\n        }\n    }\n\n\n    //\n    // See if its accepted via command line switch\n    //\n    if( argc ) {\n\n        for( i = 0; i < *argc; i++ ) {\n\n            eulaAccepted = (!_wcsicmp( argv[i], L\"/accepteula\") ||\n                            !_wcsicmp( argv[i], L\"-accepteula\"));\n            if( eulaAccepted ) {\n\n                for( ; i < *argc - 1; i++ ) {\n\n                    argv[i] = argv[i+1];\n                }\n                (*argc)--;\n                break;\n            }\n        }\n    }\n    if( ShowEulaInternal( ToolName, eulaAccepted )) {\n\n        eulaAccepted = 1;\n    }\n    return eulaAccepted != 0;\n}\n\n\nBOOL ShowEula( const TCHAR * ToolName, int *argc, PTCHAR argv[] )\n{\n    DWORD\t\teulaAccepted = 0;\n    int\t\t\ti;\n\n    if ( argc == NULL  ||  argv == NULL )  {\n        return ShowEulaW( ToolName, NULL, NULL );\n    }\n\n    //\n    // See if its accepted via command line switch\n    //\n    if( argc ) {\n\n        for( i = 0; i < *argc; i++ ) {\n\n            eulaAccepted = (!_tcsicmp( argv[i], _T(\"/accepteula\")) ||\n                            !_tcsicmp( argv[i], _T(\"-accepteula\")));\n            if( eulaAccepted ) {\n\n                for( ; i < *argc - 1; i++ ) {\n\n                    argv[i] = argv[i+1];\n                }\n                (*argc)--;\n                break;\n            }\n        }\n    }\n    if( ShowEulaInternal( ToolName, eulaAccepted )) {\n\n        eulaAccepted = 1;\n    }\n    return eulaAccepted != 0;\n}\n\n// Determine whether we are on the IoT SKU by looking at the ProductName.\nBOOL IsIoTEdition()\n{\n    HKEY\t\thKey = NULL;\n    wchar_t\t\tProductName[MAX_PATH];\n    BOOL\t\tbRet = FALSE;\t// assume \"not\" IoT Edition\n    DWORD\t\tdwSize = sizeof(ProductName);\n    DWORD\t\ttype = 0;\n\n    if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, _T(\"Software\\\\Microsoft\\\\windows nt\\\\currentversion\"), &hKey))\n    {\n        if (ERROR_SUCCESS == RegQueryValueExW(hKey, L\"ProductName\", 0, &type, (LPBYTE)ProductName, &dwSize))\n        {\n            if (!_wcsicmp(L\"iotuap\", ProductName))\n                bRet = TRUE;\n        }\n        RegCloseKey(hKey);\n    }\n\n    return bRet;\n}\n\n// Determine whether we are on the remote only edition, where we cannot prompt for user input.\nBOOL IsRemoteOnlyEdition()\n{\n    HKEY\t\thKey = NULL;\n    DWORD\t\tdwNanoServer = 0;\n    BOOL\t\tbRet = FALSE;\n    DWORD\t\tdwSize = sizeof(dwNanoServer);\n    DWORD\t\ttype = 0;\n\n    // Currently Nano is the only remote only edtion.\n    if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE, _T(\"Software\\\\Microsoft\\\\Windows NT\\\\CurrentVersion\\\\Server\\\\ServerLevels\"), &hKey))\n    {\n        if (ERROR_SUCCESS == RegQueryValueEx(hKey, _T(\"NanoServer\"), 0, &type, (LPBYTE)&dwNanoServer, &dwSize))\n        {\n            if (type == REG_DWORD && dwNanoServer == 1)\n                bRet = TRUE;\n        }\n        RegCloseKey(hKey);\n    }\n\n    return bRet;\n}\n\nBOOL IsRunningRemotely()\n{\n    // running from a remote session will not support input interaction\n    DWORD fileType = GetFileType(GetStdHandle(STD_OUTPUT_HANDLE));\n    return fileType == FILE_TYPE_PIPE;\n}\n\nDWORD ShowEulaConsole()\n{\n    DWORD dwRet = 0;\n    char ch;\n    BOOLEAN eulaAcknowledged = FALSE;\n\n    wprintf(Raw_EulaText);\n\n    while( eulaAcknowledged != TRUE )\n    {\n        printf(\"是否接受 EULA (Y/N)?\");\n        ch = (char) _getch();\n        printf(\"%c\\n\", ch);\n        if ('y' == ch || 'Y' == ch)\n        {\n            dwRet = 1;\t// EULA Accepted.\n            eulaAcknowledged = TRUE;\n        }\n\n        if ('n' == ch || 'N' == ch)\n        {\n            // EULA not accepted.\n            eulaAcknowledged = TRUE;\n        }\n    }\n    return dwRet;\n}\n\nvoid ShowEulaConsoleNoPrompt()\n{\n    wprintf_s(L\"%ls\", Raw_EulaText);\n    wprintf_s(L\"这是您首次运行此程序，需要同意 EULA 才能继续。\\n\");\n    wprintf_s(L\"可使用 -accepteula 来同意 EULA。\\n\\n\");\n\n    // exit here to avoid printing the misleading \"Eula declined\".\n    exit(1);\n}\n\nBOOL IsEulaAcceptedValueExist(HKEY hKeyRoot, LPCTSTR lpSubKey)\n{\n    HKEY\t\thKey = NULL;\n    DWORD\t\tlength;\n    DWORD       eulaAccepted = 0;\n    DWORD       ret;\n\n    //\n    // check if it is set by external channel for all tools\n    // assuming external channel do not set to WOW6432Node\n    //\n    if (RegOpenKeyEx(hKeyRoot, lpSubKey, 0, KEY_QUERY_VALUE | KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS)\n    {\n        length = sizeof(eulaAccepted);\n        ret = RegQueryValueEx(hKey, _T(\"EulaAccepted\"), NULL, NULL, (LPBYTE)&eulaAccepted, &length);\n        RegCloseKey(hKey);\n\n        if (ret == ERROR_SUCCESS && eulaAccepted)\n        {\n            return TRUE;\n        }\n    }\n    \n    return FALSE;\n}\n\nBOOL IsEulaRegkeyAdded(const TCHAR * ToolName)\n{\n    TCHAR       perToolRegKey[MAX_PATH];\n    PTCHAR      suiteRegKey = _T(\"Software\\\\Sysinternals\");\n\n    _stprintf_s(perToolRegKey, MAX_PATH, _T(\"%s\\\\%s\"), suiteRegKey, ToolName);\n\n    //\n    // check if it is set by external channel for all tools\n    // assuming external channel do not set to WOW6432Node\n    //\n    if (IsEulaAcceptedValueExist(HKEY_LOCAL_MACHINE, suiteRegKey) ||\n        IsEulaAcceptedValueExist(HKEY_CURRENT_USER, suiteRegKey))\n    {\n        return TRUE;\n    }\n\n    //\n    // per tool check\n    //\n    if (IsEulaAcceptedValueExist(HKEY_CURRENT_USER, perToolRegKey))\n    {\n        return TRUE;\n    }\n\n    return FALSE;\n}\n\nBOOL IsEulaSwitchAppended(int *argc, PTCHAR argv[])\n{\n    DWORD       eulaAccepted = 0;\n    int         i;\n\n    //\n    // See if its accepted via command line switch\n    //\n    if (*argc > 1) {\n        for (i = 1; i < *argc; i++) {\n            eulaAccepted = (!_tcsicmp(argv[i], _T(\"/accepteula\")) ||\n                !_tcsicmp(argv[i], _T(\"-accepteula\")));\n            if (eulaAccepted) {\n                break;\n            }\n        }\n    }\n\n    return eulaAccepted;\n}\n\n//\n// Determine if Eula is accepted, either already have regkey added\n// or have -accepteula switch appended\n//\nBOOL IsEulaAccepted(const TCHAR * ToolName, int *argc, PTCHAR argv[])\n{\n    return IsEulaRegkeyAdded(ToolName) || IsEulaSwitchAppended(argc, argv);\n}\n"
  },
  {
    "path": "PowerToys/src/gpo/assets/zh-CN/PowerToys.adml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright (c) Microsoft Corporation.\n     Licensed under the MIT License. -->\n<policyDefinitionResources xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" revision=\"1.15\" schemaVersion=\"1.0\" xmlns=\"http://schemas.microsoft.com/GroupPolicy/2006/07/PolicyDefinitions\">\n  <displayName>PowerToys</displayName>\n  <description>PowerToys</description>\n  <resources>\n    <stringTable>\n      <string id=\"PowerToys\">Microsoft PowerToys</string>\n\t  <string id=\"InstallerUpdates\">安装与更新</string>\n\t  <string id=\"PowerToysRun\">快捷启动器</string>\n      <string id=\"AdvancedPaste\">高级粘贴</string>\n      <string id=\"MouseWithoutBorders\">无界鼠标</string>\n      <string id=\"GeneralSettings\">常规设置</string>\n      <string id=\"NewPlus\">新建+</string>\n      <string id=\"DeprecatedPolicies\">已弃用</string>\n\n      <string id=\"SUPPORTED_POWERTOYS_0_64_0\">PowerToys 版本 0.64.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_68_0\">PowerToys 版本 0.68.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_69_0\">PowerToys 版本 0.69.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_70_0\">PowerToys 版本 0.70.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_73_0\">PowerToys 版本 0.73.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_75_0\">PowerToys 版本 0.75.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_76_0\">PowerToys 版本 0.76.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_77_0\">PowerToys 版本 0.77.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_78_0\">PowerToys 版本 0.78.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_81_0\">PowerToys 版本 0.81.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_81_1\">PowerToys 版本 0.81.1 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_83_0\">PowerToys 版本 0.83.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_84_0\">PowerToys 版本 0.84.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_85_0\">PowerToys 版本 0.85.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_86_0\">PowerToys 版本 0.86.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_88_0\">PowerToys 版本 0.88.0 或更高版本</string>\n      <string id=\"SUPPORTED_POWERTOYS_0_64_0_TO_0_87_1\">PowerToys 版本 0.64.0 至 0.87.1</string>\n\n      <string id=\"ConfigureAllUtilityGlobalEnabledStateDescription\">此策略控制所有 PowerToys 功能的启用状态。\n\n如果策略设置为“已启用”，所有功能将始终启用，用户不可以禁用任何功能。\n\n如果策略设置为“已禁用”，所有功能将始终禁用，用户不可以启用任何功能。\n\n如果策略设置为“未配置”，用户可以自由地启用和禁用功能。\n\n特定某个功能的启用状态策略将会覆盖此策略。\n</string>\n\n      <string id=\"ConfigureEnabledUtilityDescription\">此策略控制一个 PowerToys 功能的启用状态。\n\n如果策略设置为“已启用”，该功能将始终启用，用户不可以禁用这个功能。\n\n如果策略设置为“已禁用”，该功能将始终禁用，用户不可以启用这个功能。\n\n如果策略设置为“未配置”，用户可以自由地启用和禁用这个功能。\n\n该策略比“配置所有功能的启用状态”策略优先级更高，将会覆盖其设置。\n</string>\n      <string id=\"ConfigureEnabledUtilityDescriptionPDFPreviewHandler\">（注意：有用户反馈 PDF 预览与 Outlook 不兼容）\n\n此策略控制一个 PowerToys 功能的启用状态。\n\n如果策略设置为“已启用”，该功能将始终启用，用户不可以禁用这个功能。\n\n如果策略设置为“已禁用”，该功能将始终禁用，用户不可以启用这个功能。\n\n如果策略设置为“未配置”，用户可以自由地启用和禁用这个功能。\n\n该策略比“配置所有功能的启用状态”策略优先级更高，将会覆盖其设置。\n</string>\n      <string id=\"DisablePerUserInstallationDescription\">此策略控制是否允许单用户安装。\n\n如果策略设置为“已启用”，禁用单用户安装。\n\n如果策略设置为“已禁用”或“未配置”，用户可以选择仅为单用户安装 PowerToys。\n</string>\n      <string id=\"DisableAutomaticUpdateDownloadDescription\">此策略控制是否禁用自动下载和安装更新。（不过，在按流量计费的网络上，永远不会自动下载更新。）\n\n如果策略设置为“已启用”，禁用自动下载和安装更新。\n\n如果策略设置为“已禁用”或“未配置”，用户可以在设置中自行选择。\n</string>\n      <string id=\"SuspendNewUpdateToastDescription\">此策略控制是否在两次小版本更新内，不显示更新通知。（比如：如果安装的版本为 v0.60.0，则下一次显示更新提示将会是版本 v0.63.*）\n\n如果策略设置为“已启用”，减少更新通知。\n\n如果策略设置为“已禁用”或“未配置”，正常显示所有更新通知。\n\n注意：大版本更新通知始终会显示。\n\n如果启用“禁用新版本更新消息推送”策略或者在软件设置中关闭了自动更新，则该策略无效。\n</string>\n      <string id=\"DisableNewUpdateToastDescription\">此策略控制是否禁用更新通知。\n\n如果策略设置为“已启用”，不显示更新通知。\n\n如果策略设置为“已禁用”或“未配置”，用户可以选择是否显示更新通知。\n</string>\n      <string id=\"DoNotShowWhatsNewAfterUpdatesDescription\">此策略控制更新完成后是否显示更新日志窗口。\n\n如果策略设置为“已启用”，更新完成后不会自动打开更新日志。\n\n如果策略设置为“已禁用”或“未配置”，用户可以在设置中自行选择。\n</string>\n      <string id=\"AllowExperimentationDescription\">此策略控制是否允许进行 PowerToys 功能测试。如果允许测试，当用户被选中为测试组时，可以用到实验性的新功能。（功能测试只会在 Windows Insider 版本上进行。）\n\n如果策略设置为“已启用”，用户可以在 PowerToys 设置里选择是否参与功能测试。\n\n如果策略设置为“已禁用”或“未配置”，不允许参与功能测试。\n</string>\n      <string id=\"AllowDiagnosticDataDescription\">此策略控制是否允许发送 PowerToys 诊断数据。发送诊断数据可以帮助修复错误和优化性能。\n\n如果策略设置为“已启用”或“未配置”，用户可以在 PowerToys 设置里选择是否发送诊断数据。\n\n如果策略设置为“已禁用”或“未配置”，不允许发送诊断数据。\n</string>\n      <string id=\"PowerToysRunAllPluginsEnabledStateDescription\">此策略控制所有快捷启动器插件的启用状态。所有插件将会拥有相同的启用状态。\n\n如果策略设置为“已启用”，所有插件将始终启用，用户不可以禁用任何插件。\n\n如果策略设置为“已禁用”，所有插件将始终禁用，用户不可以启用任何插件。\n\n如果策略设置为“未配置”，用户可以自由地启用和禁用插件。\n\n可以通过“配置特定插件的启用状态”策略来为特定插件配置启用状态覆盖此设置。特定某个功能的启用状态策略将会覆盖此策略。\n\n注意：更改需要重新启动快捷启动器才能应用。\n</string>\n      <string id=\"PowerToysRunIndividualPluginEnabledStateDescription\">此策略控制列表中每个快捷启动器插件的启用状态。\n\n如果策略设置为“已启用”，你可以在列表中定义某个插件和其启用状态：\n  - 值名称（第一列）填入插件 ID，可以在插件文件夹内 plugin.json 文件中找到对应 ID。\n  - 值（第二列）填入数字，0 代表禁用，1 代表启用，2 代表由用户控制。\n  - 这是禁用“应用程序”插件的例子: 791FC278BA414111B8D1886DFE447410 | 0\n\n如果策略设置为“已禁用”或“未配置”，用户或“配置所有插件的启用状态”可以控制插件的启用状态。\n\n启用该策略后，你可以通过“配置所有插件的启用状态”策略，来控制列表外的其他插件的启用状态。\n\n注意：更改需要重新启动快捷启动器才能应用。\n</string>\n      <string id=\"AllowPowerToysAdvancedPasteOnlineAIModelsDescription\">此策略可以禁用高级粘贴的在线 AI 模型。\n\n如果策略设置为“已启用”或“未配置”，用户可以设置是否启用 AI 粘贴功能。\n\n如果策略设置为“已禁用”，用户不可以启用 AI 粘贴功能，不可以在粘贴面板中输入 AI 提示词，也不能配置 OpenAI 密钥。\n</string>\n      <string id=\"MwbClipboardSharingEnabledDescription\">此策略控制是否允许在多台设备之间同步剪贴板。\n\n如果策略设置为“已启用”或“未配置”，用户可以自由地启用共享剪贴板功能。\n\n如果策略设置为“已禁用”，该功能将始终禁用，用户不可以启用这个功能。\n</string>\n      <string id=\"MwbFileTransferEnabledDescription\">此策略控制是否允许在多台设备间传输剪贴板文件。\n\n如果策略设置为“已启用”或“未配置”，用户可以自由地启用共享文件功能。\n\n如果策略设置为“已禁用”，该功能将始终禁用，用户不可以启用这个功能。\n\n注意：共享文件需要开启共享剪贴板。如果禁用共享剪贴板，共享文件也将自动禁用。\n</string>\n      <string id=\"MwbUseOriginalUserInterfaceDescription\">此策略控制是否允许使用旧版无界鼠标界面。\n\n如果策略设置为“已启用”或“未配置”，用户可以自由地启用旧版界面。\n\n如果策略设置为“已禁用”，用户不可以启用旧版界面。\n</string>\n      <string id=\"MwbDisallowBlockingScreensaverDescription\">此策略控制是否允许关闭被控电脑上的屏幕保护程序。\n\n如果策略设置为“已启用”，用户无法启用阻止屏保功能，被控电脑的屏幕保护程序不会受到影响。\n\n如果策略设置为“已禁用”或“未配置”，用户可以自由地启用阻止屏保。\n</string>\n\n      <string id=\"MwbSameSubnetOnlyDescription\">此策略控制是否仅允许同一内网的连接。\n\n如果策略设置为“已启用”，该功能将始终启用，只允许连接到同一内网的电脑。\n\n如果策略设置为“已禁用”，该功能将始终禁用，允许所有连接。\n\n如果策略设置为“未配置”，用户可以自由地启用和禁用这个功能。\n</string>\n      <string id=\"MwbValidateRemoteIpDescription\">此策略控制是否通过反向 DNS 查找来验证被控设备 IP 地址。\n\n如果策略设置为“已启用”，该功能将始终启用，验证 IP 地址。\n\n如果策略设置为“已禁用”，该功能将始终禁用，不验证 IP 地址。\n\n如果策略设置为“未配置”，用户可以自由地启用和禁用这个功能。\n</string>\n      <string id=\"MwbDisableUserDefinedIpMappingRulesDescription\">此策略控制是否允许用户设定 IP 地址映射。\n\n如果策略设置为“已启用”，该功能将始终禁用，用户无法设定和使用 IP 地址映射规则。\n\n如果策略设置为“已禁用”或“未配置”，用户可以自由地启用和禁用这个功能。\n\n注意：启用该策略并不会影响组策略的预设 IP 地址映射生效。\n</string>\n      <string id=\"MwbPolicyDefinedIpMappingRulesDescription\">此策略可以设定 IP 地址映射规则。\n\n如果策略设置为“已启用”，可以设定强制的 IP 地址映射规则，用户无法改动或禁用。\n请按此格式输入，每行一个：\"hostname IP\"\n\n如果策略设置为“已禁用”或“未配置”，不使用预设规则。\n</string>\n      <string id=\"NewPlusHideTemplateFilenameExtensionDescription\">此策略控制是否显示模板文件的扩展名。\n\n如果策略设置为“已启用”，该功能将始终启用，隐藏模板文件扩展名。\n\n如果策略设置为“已禁用”，该功能将始终禁用，显示模板文件扩展名。\n\n如果策略设置为“未配置”，用户可以自由地启用和禁用这个功能。\n</string>\n\n      <string id=\"ConfigureAllUtilityGlobalEnabledState\">配置所有功能的启用状态</string>\n      <string id=\"ConfigureEnabledUtilityAdvancedPaste\">高级粘贴: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityAlwaysOnTop\">窗口置顶: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityAwake\">阻止睡眠: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityColorPicker\">取色器: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityCmdNotFound\">未找到命令: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityCropAndLock\">窗口镜像: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityEnvironmentVariables\">环境变量: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFancyZones\">窗口布局: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileLocksmith\">文件开锁匠: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerSVGPreview\">预览增强 - SVG 文件预览: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerMarkdownPreview\">预览增强 - Markdown 文件预览: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerMonacoPreview\">预览增强 - 代码文件预览: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerPDFPreview\">预览增强 - PDF 文件预览: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerGcodePreview\">预览增强 - Gcode 文件预览: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerSVGThumbnails\">预览增强 - SVG 文件缩略图: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerPDFThumbnails\">预览增强 - PDF 文件缩略图: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerGcodeThumbnails\">预览增强 - Gcode 文件缩略图: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerSTLThumbnails\">预览增强 - STL 文件缩略图: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityHostsFileEditor\">域名表: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityImageResizer\">图像裁剪器: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityKeyboardManager\">键盘修改器: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFindMyMouse\">鼠标工具箱 - 鼠标定位: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityMouseHighlighter\">鼠标工具箱 - 鼠标高亮: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityMouseJump\">鼠标工具箱 - 鼠标跳转: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityMousePointerCrosshairs\">鼠标工具箱 - 鼠标准心: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityMouseWithoutBorders\">无界鼠标: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityNewPlus\">新建+: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityPeek\">快速查看: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityPowerRename\">批量重命名: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityPowerLauncher\">快捷启动器: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityWorkspaces\">工作区: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityQuickAccent\">字母助手: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityRegistryPreview\">注册表预览: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityScreenRuler\">屏幕标尺: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityShortcutGuide\">快捷键指南: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityTextExtractor\">文本提取: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityVideoConferenceMute\">直播工具: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityZoomIt\">演示工具：启用该功能</string>\n      <string id=\"DisablePerUserInstallation\">禁用单用户安装</string>\n      <string id=\"DisableAutomaticUpdateDownload\">禁用自动下载更新</string>\n      <string id=\"DoNotShowWhatsNewAfterUpdates\">禁用更新日志弹窗</string>\n      <string id=\"SuspendNewUpdateToast\">减少新版本更新消息推送</string>\n      <string id=\"DisableNewUpdateToast\">禁用新版本更新消息推送</string>\n      <string id=\"AllowExperimentation\">允许功能测试</string>\n      <string id=\"PowerToysRunAllPluginsEnabledState\">配置所有插件的启用状态</string>\n      <string id=\"PowerToysRunIndividualPluginEnabledState\">配置特定插件的启用状态</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerQOIPreview\">预览增强 - QOI 文件预览: 启用该功能</string>\n      <string id=\"ConfigureEnabledUtilityFileExplorerQOIThumbnails\">预览增强 - QOI 文件缩略图: 启用该功能</string>\n      <string id=\"AllowPowerToysAdvancedPasteOnlineAIModels\">允许使用在线 AI 模型</string>\n      <string id=\"MwbClipboardSharingEnabled\">启用共享剪贴板</string>\n      <string id=\"MwbFileTransferEnabled\">启用文件传输</string>\n      <string id=\"MwbUseOriginalUserInterface\">启用原版界面</string>\n      <string id=\"MwbDisallowBlockingScreensaver\">禁用阻止屏保</string>\n      <string id=\"MwbSameSubnetOnly\">仅允许内网控制</string>\n      <string id=\"MwbValidateRemoteIp\">验证远程设备 IP 地址</string>\n      <string id=\"MwbDisableUserDefinedIpMappingRules\">禁用自定义 IP 地址映射</string>\n      <string id=\"MwbPolicyDefinedIpMappingRules\">预设 IP 地址映射规则</string>\n      <string id=\"NewPlusHideTemplateFilenameExtension\">隐藏模板文件扩展名</string>\n      <string id=\"AllowDiagnosticData\">允许发送诊断数据</string>\n    </stringTable>\n\n    <presentationTable>\n      <presentation id=\"PowerToysRunIndividualPluginEnabledState\">\n        <listBox refId=\"PowerToysRunIndividualPluginEnabledList\">插件管理列表:</listBox>\n      </presentation>\n      <presentation id=\"MwbPolicyDefinedIpMappingRules\">\n        <multiTextBox refId=\"MwbPolicyDefinedIpMappingsList\">IP 地址映射列表:</multiTextBox>\n      </presentation>\n    </presentationTable>\n\n  </resources>\n</policyDefinitionResources>\n\n"
  },
  {
    "path": "PowerToys/src/modules/AdvancedPaste/AdvancedPaste/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AIMistakeNote.Text\" xml:space=\"preserve\">\n    <value>注意 AI 也可能会犯错</value>\n  </data>\n  <data name=\"ClipboardEmptyWarning\" xml:space=\"preserve\">\n    <value>剪贴板为空</value>\n  </data>\n  <data name=\"OpenAINotConfigured\" xml:space=\"preserve\">\n    <value>未启用 AI 粘贴功能</value>\n  </data>\n  <data name=\"OpenAIApiKeyUnauthorized\" xml:space=\"preserve\">\n    <value>API 密钥或接入点无效</value>\n  </data>\n  <data name=\"OpenAIApiKeyTooManyRequests\" xml:space=\"preserve\">\n    <value>API 密钥额度已用尽</value>\n  </data>\n  <data name=\"OpenAIApiKeyError\" xml:space=\"preserve\">\n    <value>OpenAI 请求失败，返回状态码: </value>\n  </data>\n  <data name=\"PasteError\" xml:space=\"preserve\">\n    <value>粘贴时出现问题</value>\n  </data>\n  <data name=\"PasteActionModerated\" xml:space=\"preserve\">\n    <value>内容包含敏感信息，无法处理。请试试其他内容。</value>\n  </data>\n  <data name=\"ClipboardHistoryButton.Text\" xml:space=\"preserve\">\n    <value>剪贴板历史记录</value>\n  </data>\n  <data name=\"ClipboardHistoryButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>剪贴板历史记录</value>\n  </data>\n  <data name=\"ClipboardHistoryImage\" xml:space=\"preserve\">\n    <value>图片数据</value>\n  </data>\n  <data name=\"ClipboardHistoryItemMoreOptionsButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>更多选项</value>\n  </data>\n  <data name=\"ClipboardHistoryItemDeleteButton.Text\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"CustomFormatTextBox.PlaceholderText\" xml:space=\"preserve\">\n    <value>告诉我你想要什么格式..</value>\n  </data>\n  <data name=\"InputTxtBoxTooltip.Text\" xml:space=\"preserve\">\n    <value>告诉我你想要什么格式..</value>\n  </data>\n  <data name=\"LearnMoreLink.Text\" xml:space=\"preserve\">\n    <value>隐私政策</value>\n  </data>\n  <data name=\"LoadingText.Text\" xml:space=\"preserve\">\n    <value>正在生成结果..</value>\n  </data>\n  <data name=\"PasteAsJson\" xml:space=\"preserve\">\n    <value>粘贴为 JSON</value>\n  </data>\n  <data name=\"PasteAsMarkdown\" xml:space=\"preserve\">\n    <value>粘贴为 Markdown</value>\n  </data>\n  <data name=\"PasteAsPlainText\" xml:space=\"preserve\">\n    <value>粘贴为纯文本</value>\n  </data>\n  <data name=\"ImageToText\" xml:space=\"preserve\">\n    <value>图像转文本</value>\n  </data>\n  <data name=\"PasteAsTxtFile\" xml:space=\"preserve\">\n    <value>粘贴为 .txt 文件</value>\n  </data>\n  <data name=\"PasteAsPngFile\" xml:space=\"preserve\">\n    <value>粘贴为 .png 文件</value>\n  </data>\n  <data name=\"PasteAsHtmlFile\" xml:space=\"preserve\">\n    <value>粘贴为 .html 文件</value>\n  </data>  \n  <data name=\"PasteButtonAutomation.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>粘贴</value>\n  </data>\n  <data name=\"PasteText.Text\" xml:space=\"preserve\">\n    <value>粘贴</value>\n  </data>\n  <data name=\"ResultTitleTxt.Text\" xml:space=\"preserve\">\n    <value>结果</value>\n  </data>\n  <data name=\"RecallBtnToolTip.Text\" xml:space=\"preserve\">\n    <value>回到上一次的提示词与剪贴板数据</value>\n  </data>\n  <data name=\"RecallButtonAutomation.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>回到上一次的提示词与剪贴板数据</value>\n  </data>\n  <data name=\"SendBtnToolTip.Text\" xml:space=\"preserve\">\n    <value>生成并粘贴数据</value>\n  </data>\n  <data name=\"RegenerateBtnToolTip.Text\" xml:space=\"preserve\">\n    <value>重新生成</value>\n  </data>\n  <data name=\"RegenerateBtnAutomation.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>重新生成</value>\n  </data>\n  <data name=\"SendButtonAutomation.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>生成并粘贴数据</value>\n  </data>\n  <data name=\"SettingsBtn.Content\" xml:space=\"preserve\">\n    <value>打开设置</value>\n  </data>\n  <data name=\"SettingsBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>打开设置</value>\n  </data>\n  <data name=\"AIErrorMessage.Header\" xml:space=\"preserve\">\n    <value>AI 助手给出了如下消息：</value>\n  </data>\n  <data name=\"ThumbsDownFeedback.Text\" xml:space=\"preserve\">\n    <value>差评</value>\n  </data>\n  <data name=\"ThumbsUpFeedback.Text\" xml:space=\"preserve\">\n    <value>好评</value>\n  </data>\n  <data name=\"WindowTitle\" xml:space=\"preserve\">\n    <value>高级粘贴</value>\n  </data>\n  <data name=\"PreviousResultBtnToolTip.Text\" xml:space=\"preserve\">\n    <value>上一条</value>\n  </data>\n  <data name=\"PreviousResultBtnAutomation.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>上一条</value>\n  </data>\n  <data name=\"NextResultBtnToolTip.Text\" xml:space=\"preserve\">\n    <value>下一条</value>\n  </data>\n  <data name=\"NextResultBtnAutomation.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>下一条</value>\n  </data>\n  <data name=\"PrivacyLink.Text\" xml:space=\"preserve\">\n    <value>OpenAI 隐私政策</value>\n  </data>\n  <data name=\"TermsLink.Text\" xml:space=\"preserve\">\n    <value>OpenAI 使用条款</value>\n  </data>\n  <data name=\"OpenAIGpoDisabled\" xml:space=\"preserve\">\n    <value>组策略已禁止 AI 功能</value>\n  </data>\n  <data name=\"CtrlKey\" xml:space=\"preserve\">\n    <value>Ctrl</value>\n  </data>\n  <data name=\"PasteAsFile_FilePrefix\" xml:space=\"preserve\">\n    <value>PowerToys_Paste_</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/CropAndLock/CropAndLock/main.cpp",
    "content": "﻿#include \"pch.h\"\n#include \"SettingsWindow.h\"\n#include \"OverlayWindow.h\"\n#include \"CropAndLockWindow.h\"\n#include \"ThumbnailCropAndLockWindow.h\"\n#include \"ReparentCropAndLockWindow.h\"\n#include \"ModuleConstants.h\"\n#include \"trace.h\"\n\n#include <common/interop/shared_constants.h>\n\n#include <common/utils/gpo.h>\n#include <common/utils/logger_helper.h>\n#include <common/utils/ProcessWaiter.h>\n#include <common/utils/UnhandledExceptionHandler.h>\n#include <common/utils/winapi_error.h>\n\n#include <common/Telemetry/EtwTrace/EtwTrace.h>\n\n#pragma comment(linker, \"/manifestdependency:\\\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\\\"\")\n\nnamespace winrt\n{\n    using namespace Windows::Foundation;\n    using namespace Windows::Foundation::Numerics;\n    using namespace Windows::UI;\n    using namespace Windows::UI::Composition;\n}\n\nnamespace util\n{\n    using namespace robmikh::common::desktop;\n}\n\nconst std::wstring instanceMutexName = L\"Local\\\\PowerToys_CropAndLock_InstanceMutex\";\nbool m_running = true;\n\nint WINAPI wWinMain(_In_ HINSTANCE, _In_opt_ HINSTANCE, _In_ PWSTR lpCmdLine, _In_ int)\n{\n    // Initialize COM\n    winrt::init_apartment(winrt::apartment_type::single_threaded);\n\n    Trace::CropAndLock::RegisterProvider();\n\n    Shared::Trace::ETWTrace trace;\n    trace.UpdateState(true);\n\n    // Initialize logger automatic logging of exceptions.\n    LoggerHelpers::init_logger(NonLocalizable::ModuleKey, L\"\", LogSettings::cropAndLockLoggerName);\n    InitUnhandledExceptionHandler();\n\n    if (powertoys_gpo::getConfiguredCropAndLockEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled)\n    {\n        Logger::warn(L\"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.\");\n        return 0;\n    }\n\n    // Before we do anything, check to see if we're already running. If we are,\n    // the hotkey won't register and we'll fail. Instead, we should tell the user\n    // to kill the other instance and exit this one.\n    auto mutex = CreateMutex(nullptr, true, instanceMutexName.c_str());\n    if (mutex == nullptr)\n    {\n        Logger::error(L\"Failed to create mutex. {}\", get_last_error_or_default(GetLastError()));\n    }\n\n    if (GetLastError() == ERROR_ALREADY_EXISTS)\n    {\n        // CropAndLock is already open.\n        return 1;\n    }\n\n    std::wstring pid = std::wstring(lpCmdLine);\n    if (pid.empty())\n    {\n        Logger::warn(L\"Tried to run Crop And Lock as a standalone.\");\n        MessageBoxW(nullptr, L\"窗口镜像功能不能独立使用，请从 PowerToys 启动。\", L\"CropAndLock\", MB_ICONERROR);\n        return 1;\n    }\n\n    auto mainThreadId = GetCurrentThreadId();\n    ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) {\n        if (err != ERROR_SUCCESS)\n        {\n            Logger::error(L\"Failed to wait for parent process exit. {}\", get_last_error_or_default(err));\n        }\n        else\n        {\n            Logger::trace(L\"PowerToys runner exited.\");\n        }\n\n        Logger::trace(L\"Exiting CropAndLock\");\n        PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);\n    });\n\n    // NOTE: reparenting a window with a different DPI context has consequences.\n    //       See https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setparent#remarks\n    //       for more info.\n    winrt::check_bool(SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2));\n\n    // Create the DispatcherQueue that the compositor needs to run\n    auto controller = util::CreateDispatcherQueueControllerForCurrentThread();\n\n    // Setup Composition\n    auto compositor = winrt::Compositor();\n\n    // Create our overlay window\n    std::unique_ptr<OverlayWindow> overlayWindow;\n\n    // Keep a list of our cropped windows\n    std::vector<std::shared_ptr<CropAndLockWindow>> croppedWindows;\n\n    // Handles and thread for the events sent from runner\n    HANDLE m_reparent_event_handle;\n    HANDLE m_thumbnail_event_handle;\n    HANDLE m_exit_event_handle;\n    std::thread m_event_triggers_thread;\n\n    std::function<void(HWND)> removeWindowCallback = [&](HWND windowHandle) {\n        if (!m_running)\n        {\n            // If we're not running, the reference to croppedWindows might no longer be valid and cause a crash at exit time, due to being called by destructors after wWinMain returns.\n            return;\n        }\n\n        auto pos = std::find_if(croppedWindows.begin(), croppedWindows.end(), [windowHandle](auto window) { return window->Handle() == windowHandle; });\n        if (pos != croppedWindows.end())\n        {\n            croppedWindows.erase(pos);\n        }\n    };\n\n    std::function<void(CropAndLockType)> ProcessCommand = [&](CropAndLockType mode) {\n        std::function<void(HWND, RECT)> windowCroppedCallback = [&, mode](HWND targetWindow, RECT cropRect) {\n            auto targetInfo = util::WindowInfo(targetWindow);\n            // TODO: Fix WindowInfo.h to not contain the null char at the end.\n            auto nullCharIndex = std::wstring::npos;\n            do\n            {\n                nullCharIndex = targetInfo.Title.rfind(L'\\0');\n                if (nullCharIndex != std::wstring::npos)\n                {\n                    targetInfo.Title.erase(nullCharIndex);\n                }\n            } while (nullCharIndex != std::wstring::npos);\n\n            std::wstringstream titleStream;\n            titleStream << targetInfo.Title << L\" (镜像)\";\n            auto title = titleStream.str();\n\n            std::shared_ptr<CropAndLockWindow> croppedWindow;\n            switch (mode)\n            {\n            case CropAndLockType::Reparent:\n                croppedWindow = std::make_shared<ReparentCropAndLockWindow>(title, 800, 600);\n                Logger::trace(L\"Creating a reparent window\");\n                Trace::CropAndLock::CreateReparentWindow();\n                break;\n            case CropAndLockType::Thumbnail:\n                croppedWindow = std::make_shared<ThumbnailCropAndLockWindow>(title, 800, 600);\n                Logger::trace(L\"Creating a thumbnail window\");\n                Trace::CropAndLock::CreateThumbnailWindow();\n                break;\n            default:\n                return;\n            }\n            croppedWindow->CropAndLock(targetWindow, cropRect);\n            croppedWindow->OnClosed(removeWindowCallback);\n            croppedWindows.push_back(croppedWindow);\n        };\n\n        overlayWindow.reset();\n\n        // Get the current window with focus\n        auto foregroundWindow = GetForegroundWindow();\n        if (foregroundWindow != nullptr)\n        {\n            bool match = false;\n            for (auto&& croppedWindow : croppedWindows)\n            {\n                if (foregroundWindow == croppedWindow->Handle())\n                {\n                    match = true;\n                    break;\n                }\n            }\n            if (!match)\n            {\n                overlayWindow = std::make_unique<OverlayWindow>(compositor, foregroundWindow, windowCroppedCallback);\n            }\n        }\n    };\n\n    // Start a thread to listen on the events.\n    m_reparent_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::CROP_AND_LOCK_REPARENT_EVENT);\n    m_thumbnail_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::CROP_AND_LOCK_THUMBNAIL_EVENT);\n    m_exit_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::CROP_AND_LOCK_EXIT_EVENT);\n    if (!m_reparent_event_handle || !m_thumbnail_event_handle || !m_exit_event_handle)\n    {\n        Logger::warn(L\"Failed to create events. {}\", get_last_error_or_default(GetLastError()));\n        return 1;\n    }\n\n    m_event_triggers_thread = std::thread([&]() {\n        MSG msg;\n        HANDLE event_handles[3] = { m_reparent_event_handle, m_thumbnail_event_handle, m_exit_event_handle };\n        while (m_running)\n        {\n            DWORD dwEvt = MsgWaitForMultipleObjects(3, event_handles, false, INFINITE, QS_ALLINPUT);\n            if (!m_running)\n            {\n                break;\n            }\n            switch (dwEvt)\n            {\n            case WAIT_OBJECT_0:\n            {\n                // Reparent Event\n                bool enqueueSucceeded = controller.DispatcherQueue().TryEnqueue([&]() {\n                    ProcessCommand(CropAndLockType::Reparent);\n                });\n                if (!enqueueSucceeded)\n                {\n                    Logger::error(\"Couldn't enqueue message to reparent a window.\");\n                }\n                break;\n            }\n            case WAIT_OBJECT_0 + 1:\n            {\n                // Thumbnail Event\n                bool enqueueSucceeded = controller.DispatcherQueue().TryEnqueue([&]() {\n                    ProcessCommand(CropAndLockType::Thumbnail);\n                });\n                if (!enqueueSucceeded)\n                {\n                    Logger::error(\"Couldn't enqueue message to thumbnail a window.\");\n                }\n                break;\n            }\n            case WAIT_OBJECT_0 + 2:\n            {\n                // Exit Event\n                Logger::trace(L\"Received an exit event.\");\n                PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);\n                break;\n            }\n            case WAIT_OBJECT_0 + 3:\n                if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))\n                {\n                    TranslateMessage(&msg);\n                    DispatchMessageW(&msg);\n                }\n                break;\n            default:\n                break;\n            }\n        }\n    });\n\n    // Message pump\n    MSG msg = {};\n    while (GetMessageW(&msg, nullptr, 0, 0))\n    {\n        TranslateMessage(&msg);\n        DispatchMessageW(&msg);\n    }\n\n    trace.Flush();\n\n    Trace::CropAndLock::UnregisterProvider();\n\n    m_running = false;\n    // Needed to unblock MsgWaitForMultipleObjects one last time\n    SetEvent(m_reparent_event_handle);\n    CloseHandle(m_reparent_event_handle);\n    CloseHandle(m_thumbnail_event_handle);\n    CloseHandle(m_exit_event_handle);\n    m_event_triggers_thread.join();\n\n    return util::ShutdownDispatcherQueueControllerAndWait(controller, static_cast<int>(msg.wParam));\n}\n"
  },
  {
    "path": "PowerToys/src/modules/EnvironmentVariables/EnvironmentVariablesUILib/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"DefaultSetsLabel.Text\" xml:space=\"preserve\">\n    <value>默认变量</value>\n  </data>\n  <data name=\"DefaultVariablesLbl.Text\" xml:space=\"preserve\">\n    <value>默认变量</value>\n  </data>\n  <data name=\"NewProfileBtn.Text\" xml:space=\"preserve\">\n    <value>新建模板</value>\n  </data>\n  <data name=\"ProfilesDescriptionLbl.Text\" xml:space=\"preserve\">\n    <value>通过模板来快速设定一组环境变量预设，模板变量优先于用户和系统变量。</value>\n  </data>\n  <data name=\"ProfilesLbl.Text\" xml:space=\"preserve\">\n    <value>模板</value>\n  </data>\n  <data name=\"System\" xml:space=\"preserve\">\n    <value>系统</value>\n  </data>\n  <data name=\"User\" xml:space=\"preserve\">\n    <value>用户</value>\n  </data>\n  <data name=\"WindowTitle\" xml:space=\"preserve\">\n    <value>环境变量编辑器</value>\n    <comment>Title of the window when running as user</comment>\n  </data>\n  <data name=\"EditDialog.CloseButtonText\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"EditVariableDialog_Title\" xml:space=\"preserve\">\n    <value>编辑变量</value>\n  </data>\n  <data name=\"NewProfileNameTxtBox.Header\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"SaveBtn\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"ValueTxtBox.Header\" xml:space=\"preserve\">\n    <value>值</value>\n  </data>\n  <data name=\"AddBtn\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"AddNewProfileDialog_Title\" xml:space=\"preserve\">\n    <value>新建模板</value>\n  </data>\n  <data name=\"NewProfileEnabled.Header\" xml:space=\"preserve\">\n    <value>立即应用</value>\n  </data>\n  <data name=\"AddVariableBtn.Text\" xml:space=\"preserve\">\n    <value>添加变量</value>\n  </data>\n  <data name=\"AddNewVariableName.Header\" xml:space=\"preserve\">\n    <value>名称</value>\n    <comment>Name as in Environment variable name</comment>\n  </data>\n  <data name=\"AddNewVariableValue.Header\" xml:space=\"preserve\">\n    <value>值</value>\n    <comment>Value as in Environment variable value</comment>\n  </data>\n  <data name=\"ExistingVariableSegmentedButton.Content\" xml:space=\"preserve\">\n    <value>已有变量</value>\n  </data>\n  <data name=\"NewVariableSegmentedButton.Content\" xml:space=\"preserve\">\n    <value>新建变量</value>\n  </data>\n  <data name=\"WindowAdminTitle\" xml:space=\"preserve\">\n    <value>管理员权限: 环境变量编辑器</value>\n    <comment>Title of the window when running as administrator</comment>\n  </data>\n  <data name=\"CancelAddVariableBtn.Content\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"ConfirmAddVariableBtn.Content\" xml:space=\"preserve\">\n    <value>添加</value>\n  </data>\n  <data name=\"AppliedVariablesDescriptionLbl.Text\" xml:space=\"preserve\">\n    <value>当前所有环境变量，包括模板、用户和系统所设置的变量。</value>\n  </data>\n  <data name=\"AppliedVariablesLbl.Text\" xml:space=\"preserve\">\n    <value>当前变量</value>\n  </data>\n  <data name=\"NewProfileVariablesListViewHeader.Text\" xml:space=\"preserve\">\n    <value>变量</value>\n  </data>\n  <data name=\"DeleteMenuItem.Text\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"Delete_Dialog_Description\" xml:space=\"preserve\">\n    <value>确定删除此模板？如果该模板已启用，它添加的变量也将被删除。</value>\n  </data>\n  <data name=\"EditSystemDefaultSetInfoBar.Text\" xml:space=\"preserve\">\n    <value>编辑系统环境变量需要管理员权限</value>\n  </data>\n  <data name=\"No\" xml:space=\"preserve\">\n    <value>否</value>\n  </data>\n  <data name=\"Yes\" xml:space=\"preserve\">\n    <value>是</value>\n  </data>\n  <data name=\"StateNotUpToDateTitle\" xml:space=\"preserve\">\n    <value>变量发生改动</value>\n  </data>\n  <data name=\"StateNotUpToDateOnStartupMsg\" xml:space=\"preserve\">\n    <value>由模板添加的变量已被修改，在重新启用模板前，请检查改动情况</value>\n  </data>\n  <data name=\"CancelBtn\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"StateNotUpToDateEnvironmentMessageReceivedMsg\" xml:space=\"preserve\">\n    <value>变量已被其他程序修改，刷新获取最新值</value>\n  </data>\n  <data name=\"AddVariable_Title\" xml:space=\"preserve\">\n    <value>添加变量</value>\n  </data>\n  <data name=\"Delete_Variable_Description\" xml:space=\"preserve\">\n    <value>确定删除这个变量吗？</value>\n  </data>\n  <data name=\"EditProfileDialog_Title\" xml:space=\"preserve\">\n    <value>编辑模板</value>\n  </data>\n  <data name=\"AddVariableTooltip.Text\" xml:space=\"preserve\">\n    <value>添加变量</value>\n  </data>\n  <data name=\"DefaultVariablesDescriptionLbl.Text\" xml:space=\"preserve\">\n    <value>修改用户和系统的环境变量。</value>\n  </data>\n  <data name=\"EditItem.Text\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"More_Options_ButtonTooltip.Text\" xml:space=\"preserve\">\n    <value>更多选项</value>\n  </data>\n  <data name=\"MoveDown.Text\" xml:space=\"preserve\">\n    <value>下移</value>\n  </data>\n  <data name=\"MoveUp.Text\" xml:space=\"preserve\">\n    <value>上移</value>\n  </data>\n  <data name=\"InsertListEntryBefore.Text\" xml:space=\"preserve\">\n    <value>在前面插入</value>\n  </data>\n  <data name=\"InsertListEntryAfter.Text\" xml:space=\"preserve\">\n    <value>在后面插入</value>\n  </data>\n  <data name=\"NewProfileVariablesListViewApplyToSystemHeader.Text\" xml:space=\"preserve\">\n    <value>应用到系统？</value>\n  </data>\n  <data name=\"RemoveListItem.Text\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"RemoveItem.Text\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"AddVariableContent.Content\" xml:space=\"preserve\">\n    <value>添加变量</value>\n  </data>\n  <data name=\"ProfileNotApplicableTitle\" xml:space=\"preserve\">\n    <value>无法应用模板。</value>\n  </data>\n  <data name=\"StateProfileNotApplicableMsg\" xml:space=\"preserve\">\n    <value>变量或备份变量无效。</value>\n  </data>\n  <data name=\"VariableIsAppliedByActiveProfileTooltip.Text\" xml:space=\"preserve\">\n    <value>该变量由已启用的模板写入</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/FileLocksmith/FileLocksmithContextMenu/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\"\n    xmlns=\"\"\n    xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"\n    xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"File_Locksmith_Context_Menu_Entry\" xml:space=\"preserve\">\n    <value>查看文件占用</value>\n    <comment>This text will be shown when the user opens the context menu (right clicks) a file. File Locksmith is the product name, do not loc.</comment>\n  </data>\n  <data name=\"File_Locksmith_App_Name\" xml:space=\"preserve\">\n    <value>文件开锁匠</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/FileLocksmith/FileLocksmithContextMenu/dllmain.cpp",
    "content": "// dllmain.cpp : Defines the entry point for the DLL application.\n#include \"pch.h\"\n\n#include <common/telemetry/EtwTrace/EtwTrace.h>\n#include <common/utils/process_path.h>\n#include <common/utils/resources.h>\n#include <common/utils/elevation.h>\n\n#include \"FileLocksmithLib/IPC.h\"\n#include \"FileLocksmithLib/Settings.h\"\n#include \"FileLocksmithLib/Trace.h\"\n\n#include <Shlwapi.h>\n#include <shobjidl_core.h>\n#include <string>\n#include <wrl/module.h>\n\n#include \"Generated Files/resource.h\"\n\n\nusing namespace Microsoft::WRL;\n\nHINSTANCE g_hInst = 0;\nShared::Trace::ETWTrace trace(L\"FileLocksmithContextMenu\");\n\nBOOL APIENTRY DllMain( HMODULE hModule,\n                       DWORD  ul_reason_for_call,\n                       LPVOID lpReserved\n                     )\n{\n    switch (ul_reason_for_call)\n    {\n    case DLL_PROCESS_ATTACH:\n        g_hInst = hModule;\n        Trace::RegisterProvider();\n        break;\n    case DLL_PROCESS_DETACH:\n        Trace::UnregisterProvider();\n        break;\n    }\n    return TRUE;\n}\n\nclass __declspec(uuid(\"AAF1E27D-4976-49C2-8895-AAFA743C0A7E\")) FileLocksmithContextMenuCommand final : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IExplorerCommand, IObjectWithSite>\n{\npublic:\n    virtual const wchar_t* Title() { return L\"File Locksmith\"; }\n    virtual const EXPCMDFLAGS Flags() { return ECF_DEFAULT; }\n    virtual const EXPCMDSTATE State(_In_opt_ IShellItemArray* selection) { return ECS_ENABLED; }\n\n    // IExplorerCommand\n    IFACEMETHODIMP GetTitle(_In_opt_ IShellItemArray* items, _Outptr_result_nullonfailure_ PWSTR* name)\n    {\n        return SHStrDup(context_menu_caption.c_str(), name);\n    }\n\n    IFACEMETHODIMP GetIcon(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* icon)\n    {\n        std::wstring iconResourcePath = get_module_folderpath(g_hInst);\n        iconResourcePath += L\"\\\\Assets\\\\FileLocksmith\\\\\";\n        iconResourcePath += L\"FileLocksmith.ico\";\n        return SHStrDup(iconResourcePath.c_str(), icon);\n    }\n\n    IFACEMETHODIMP GetToolTip(_In_opt_ IShellItemArray*, _Outptr_result_nullonfailure_ PWSTR* infoTip)\n    {\n        *infoTip = nullptr;\n        return E_NOTIMPL;\n    }\n\n    IFACEMETHODIMP GetCanonicalName(_Out_ GUID* guidCommandName)\n    {\n        *guidCommandName = __uuidof(this);\n        return S_OK;\n    }\n\n    IFACEMETHODIMP GetState(_In_opt_ IShellItemArray* selection, _In_ BOOL okToBeSlow, _Out_ EXPCMDSTATE* cmdState)\n    {\n        *cmdState = ECS_ENABLED;\n\n        if (!FileLocksmithSettingsInstance().GetEnabled())\n        {\n            *cmdState = ECS_HIDDEN;\n        }\n\n        if (FileLocksmithSettingsInstance().GetShowInExtendedContextMenu())\n        {\n            *cmdState = ECS_HIDDEN;\n        }\n\n        return S_OK;\n    }\n\n    IFACEMETHODIMP Invoke(_In_opt_ IShellItemArray* selection, _In_opt_ IBindCtx*) noexcept\n    {\n        trace.UpdateState(true);\n\n        Trace::Invoked();\n        ipc::Writer writer;\n\n        if (selection == nullptr)\n        {\n            return S_OK;\n        }\n\n        if (HRESULT result = writer.start(); FAILED(result))\n        {\n            Trace::InvokedRet(result);\n\n            trace.Flush();\n            trace.UpdateState(false);\n            return result;\n        }\n\n        std::wstring path = get_module_folderpath(g_hInst);\n        path = path + L\"\\\\PowerToys.FileLocksmithUI.exe\";\n\n        HRESULT result;\n\n        if (!RunNonElevatedEx(path.c_str(), L\"\", get_module_folderpath(g_hInst)))\n        {\n            result = E_FAIL;\n            Trace::InvokedRet(result);\n\n            trace.Flush();\n            trace.UpdateState(false);\n\n            return result;\n        }\n\n        DWORD num_items;\n        selection->GetCount(&num_items);\n\n        for (DWORD i = 0; i < num_items; i++)\n        {\n            IShellItem* item;\n            result = selection->GetItemAt(i, &item);\n            if (SUCCEEDED(result))\n            {\n                LPWSTR file_path;\n                result = item->GetDisplayName(SIGDN_FILESYSPATH, &file_path);\n                if (SUCCEEDED(result))\n                {\n                    // TODO Aggregate items and send to UI\n                    writer.add_path(file_path);\n                    CoTaskMemFree(file_path);\n                }\n\n                item->Release();\n            }\n        }\n\n        Trace::InvokedRet(S_OK);\n\n        trace.Flush();\n        trace.UpdateState(false);\n\n        return S_OK;\n    }\n\n    IFACEMETHODIMP GetFlags(_Out_ EXPCMDFLAGS* flags)\n    {\n        *flags = Flags();\n        return S_OK;\n    }\n    IFACEMETHODIMP EnumSubCommands(_COM_Outptr_ IEnumExplorerCommand** enumCommands)\n    {\n        *enumCommands = nullptr;\n        return E_NOTIMPL;\n    }\n\n    // IObjectWithSite\n    IFACEMETHODIMP SetSite(_In_ IUnknown* site) noexcept\n    {\n        m_site = site;\n        return S_OK;\n    }\n    IFACEMETHODIMP GetSite(_In_ REFIID riid, _COM_Outptr_ void** site) noexcept { return m_site.CopyTo(riid, site); }\n\nprotected:\n    ComPtr<IUnknown> m_site;\n\nprivate:\n    std::wstring context_menu_caption = GET_RESOURCE_STRING_FALLBACK(IDS_FILE_LOCKSMITH_CONTEXT_MENU_ENTRY, L\"鿴ļռ\"); // ANSI PLZ\n};\n\nCoCreatableClass(FileLocksmithContextMenuCommand)\nCoCreatableClassWrlCreatorMapInclude(FileLocksmithContextMenuCommand)\n\n\nSTDAPI DllGetActivationFactory(_In_ HSTRING activatableClassId, _COM_Outptr_ IActivationFactory** factory)\n{\n    return Module<ModuleType::InProc>::GetModule().GetActivationFactory(activatableClassId, factory);\n}\n\nSTDAPI DllCanUnloadNow()\n{\n    return Module<InProc>::GetModule().GetObjectCount() == 0 ? S_OK : S_FALSE;\n}\n\nSTDAPI DllGetClassObject(_In_ REFCLSID rclsid, _In_ REFIID riid, _COM_Outptr_ void** instance)\n{\n    return Module<InProc>::GetModule().GetClassObject(rclsid, riid, instance);\n}\n"
  },
  {
    "path": "PowerToys/src/modules/FileLocksmith/FileLocksmithExt/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"FileLocksmith_Context_Menu_Entry\" xml:space=\"preserve\">\n    <value>查看文件占用</value>\n    <comment>This text will be shown when the user opens the context menu (right clicks) a file. File Locksmith is the product name, do not loc.</comment>\n  </data>\n  <data name=\"FileLocksmith_PowerToyName\" xml:space=\"preserve\">\n    <value>文件开锁匠</value>\n    <comment>Localized name of the PowerToy.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/FileLocksmith/FileLocksmithUI/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AppTitle\" xml:space=\"preserve\">\n    <value>文件开锁匠</value>\n    <comment>Title of the window when running as user.</comment>\n  </data>\n  <data name=\"EmptyListDescription.Text\" xml:space=\"preserve\">\n    <value>无占用</value>\n  </data>\n  <data name=\"EndTask.Text\" xml:space=\"preserve\">\n    <value>结束任务</value>\n  </data>\n  <data name=\"Files.Text\" xml:space=\"preserve\">\n    <value>占用文件</value>\n  </data>\n  <data name=\"ProcessFilesListDialog.Title\" xml:space=\"preserve\">\n    <value>占用文件</value>\n  </data>\n  <data name=\"ProcessFilesListDialog.CloseButtonText\" xml:space=\"preserve\">\n    <value>关闭</value>\n    <comment>As in, close a dialog prompt.</comment>\n  </data>\n  <data name=\"PathsTooltipDescription.Text\" xml:space=\"preserve\">\n    <value>点击查看所有选中文件</value>\n    <comment>Paths as in file paths that were selected for the utility to check.</comment>\n  </data>\n  <data name=\"ProcessIsSystemUserWarning.Text\" xml:space=\"preserve\">\n    <value>此为系统程序，结束它可能导致系统故障。</value>\n  </data>\n  <data name=\"SelectedFilesListDialog.Title\" xml:space=\"preserve\">\n    <value>选中文件列表</value>\n    <comment>Paths as in file paths that were selected for the utility to check.</comment>\n  </data>\n  <data name=\"SelectedFilesListDialog.CloseButtonText\" xml:space=\"preserve\">\n    <value>关闭</value>\n    <comment>As in, close a dialog prompt.</comment>\n  </data>\n  <data name=\"NoFilesSelected.Text\" xml:space=\"preserve\">\n    <value>未选择文件</value>\n  </data>\n  <data name=\"ProcessID.Header\" xml:space=\"preserve\">\n    <value>进程 ID</value>\n  </data>\n  <data name=\"Reload.Text\" xml:space=\"preserve\">\n    <value>刷新</value>\n  </data>\n  <data name=\"RestartAsAdmin.Text\" xml:space=\"preserve\">\n    <value>以管理员身份重启</value>\n  </data>\n  <data name=\"User.Header\" xml:space=\"preserve\">\n    <value>用户</value>\n  </data>\n  <data name=\"AppAdminTitle\" xml:space=\"preserve\">\n    <value>管理员权限: 文件开锁匠</value>\n    <comment>Title of the window when running as administrator.</comment>\n  </data>\n  <data name=\"ShowProcessFiles.Text\" xml:space=\"preserve\">\n    <value>查看</value>\n    <comment>Show files for the selected process</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/Hosts/HostsUILib/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Active.Header\" xml:space=\"preserve\">\n    <value>启用</value>\n  </data>\n  <data name=\"ActiveToggle.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>启用</value>\n  </data>\n  <data name=\"AddBtn\" xml:space=\"preserve\">\n    <value>添加</value>\n  </data>\n  <data name=\"AddEntry.Text\" xml:space=\"preserve\">\n    <value>添加条目</value>\n  </data>\n  <data name=\"AddEntryBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>添加条目</value>\n  </data>\n  <data name=\"AddEntryBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>添加条目 (Ctrl+N)</value>\n  </data>\n  <data name=\"AddEntryLink.Content\" xml:space=\"preserve\">\n    <value>添加一个条目</value>\n  </data>\n  <data name=\"AdditionalLinesBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>注释</value>\n  </data>\n  <data name=\"AdditionalLinesBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>注释</value>\n  </data>\n  <data name=\"AdditionalLinesDialog.CloseButtonText\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"AdditionalLinesDialog.PrimaryButtonText\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"AdditionalLinesDialog.Title\" xml:space=\"preserve\">\n    <value>注释</value>\n  </data>\n  <data name=\"AddNewEntryDialog_Title\" xml:space=\"preserve\">\n    <value>添加条目</value>\n  </data>\n  <data name=\"Address.Header\" xml:space=\"preserve\">\n    <value>地址</value>\n    <comment>\"Address\" refers to the IP address of the entry</comment>\n  </data>\n  <data name=\"AddressFilter.Header\" xml:space=\"preserve\">\n    <value>地址</value>\n    <comment>\"Address\" refers to the IP address of the entry</comment>\n  </data>\n  <data name=\"ClearFiltersBtn.Content\" xml:space=\"preserve\">\n    <value>清除筛选</value>\n  </data>\n  <data name=\"ClearFiltersBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>清除筛选</value>\n  </data>\n  <data name=\"ClearFiltersLink.Content\" xml:space=\"preserve\">\n    <value>清除筛选</value>\n  </data>\n  <data name=\"Comment.Header\" xml:space=\"preserve\">\n    <value>备注</value>\n    <comment>\"Comment\" refers to the comment of the entry</comment>\n  </data>\n  <data name=\"CommentFilter.Header\" xml:space=\"preserve\">\n    <value>备注</value>\n    <comment>\"Comment\" refers to the comment of the entry</comment>\n  </data>\n  <data name=\"Delete.Text\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"DeleteDialog.CloseButtonText\" xml:space=\"preserve\">\n    <value>否</value>\n  </data>\n  <data name=\"DeleteDialog.PrimaryButtonText\" xml:space=\"preserve\">\n    <value>是</value>\n  </data>\n  <data name=\"DeleteDialogAreYouSure.Text\" xml:space=\"preserve\">\n    <value>确定删除此条目？</value>\n  </data>\n  <data name=\"DeleteEntryBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"DeleteEntryBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>删除 (Delete)</value>\n    <comment>\"Delete\" between parentheses refers to the Delete keyboard key</comment>\n  </data>\n  <data name=\"Duplicate.Text\" xml:space=\"preserve\">\n    <value>复制</value>\n    <comment>Refers to the action of duplicate an existing entry</comment>\n  </data>\n  <data name=\"DuplicateEntryIcon.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>地址重复</value>\n  </data>\n  <data name=\"Edit.Text\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"EmptyFilterResults.Text\" xml:space=\"preserve\">\n    <value>无筛选结果</value>\n  </data>\n  <data name=\"EmptyHosts.Text\" xml:space=\"preserve\">\n    <value>未储存任何条目</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"Entries.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>条目</value>\n  </data>\n  <data name=\"EntryDialog.CloseButtonText\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"FileChanged.Message\" xml:space=\"preserve\">\n    <value>域名表文件被其他软件改动。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"FileSaveError_FileInUse\" xml:space=\"preserve\">\n    <value>无法保存域名表文件，因为文件被其他软件所占用。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"FileSaveError_Generic\" xml:space=\"preserve\">\n    <value>无法保存域名表文件。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"FileSaveError_NotElevated\" xml:space=\"preserve\">\n    <value>无法保存域名表文件，需要管理员权限。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"FileSaveError_ReadOnly\" xml:space=\"preserve\">\n    <value>无法保存域名表文件，文件不允许写入。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"FilterBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>筛选</value>\n  </data>\n  <data name=\"FilterBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>筛选</value>\n  </data>\n  <data name=\"Hosts.Header\" xml:space=\"preserve\">\n    <value>域名</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc // 并不是</comment>\n  </data>\n  <data name=\"Hosts.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>空格分隔多个域名（比如：server server.local），一次最多九个</value>\n    <comment>Do not localize \"server\" and \"server.local\"</comment>\n  </data>\n  <data name=\"HostsFilter.Header\" xml:space=\"preserve\">\n    <value>域名</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc // 并不是</comment>\n  </data>\n  <data name=\"MakeWritable.Content\" xml:space=\"preserve\">\n    <value>获取写入权限</value>\n  </data>\n  <data name=\"MoveDown.Text\" xml:space=\"preserve\">\n    <value>下移</value>\n  </data>\n  <data name=\"MoveUp.Text\" xml:space=\"preserve\">\n    <value>上移</value>\n  </data>\n  <data name=\"OpenHostsFileBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>打开文本编辑器</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"OpenHostsFileBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>打开文本编辑器</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"Ping.Text\" xml:space=\"preserve\">\n    <value>Ping 测试</value>\n    <comment>\"Ping\" refers to the command-line utility, do not loc</comment>\n  </data>\n  <data name=\"PingIcon.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>Ping 结果</value>\n    <comment>\"Ping\" refers to the command-line utility, do not loc</comment>\n  </data>\n  <data name=\"Reload.Content\" xml:space=\"preserve\">\n    <value>重新加载</value>\n  </data>\n  <data name=\"SettingsBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"SettingsBtn.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"ShowOnlyDuplicates.Header\" xml:space=\"preserve\">\n    <value>仅显示地址重复的条目</value>\n  </data>\n  <data name=\"TooManyHostsTeachingTip.Subtitle\" xml:space=\"preserve\">\n    <value>每条最多填写九个域名，太长的条目已被拆分，保存后生效。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"TooManyHostsTeachingTip.Title\" xml:space=\"preserve\">\n    <value>域名数量过多</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"EntryAddressIsInvalidWarning.Text\" xml:space=\"preserve\">\n    <value>地址不符合 IPv4 或 IPv6 格式</value>\n  </data>\n  <data name=\"EntryHostsIsInvalidWarning.Text\" xml:space=\"preserve\">\n    <value>域名列表不符合格式</value>\n  </data>\n  <data name=\"UpdateBtn\" xml:space=\"preserve\">\n    <value>更新</value>\n  </data>\n  <data name=\"UpdateEntry_Title\" xml:space=\"preserve\">\n    <value>更新条目</value>\n  </data>\n  <data name=\"WarningDialog_AcceptBtn\" xml:space=\"preserve\">\n    <value>继续</value>\n  </data>\n  <data name=\"WarningDialog_QuitBtn\" xml:space=\"preserve\">\n    <value>退出</value>\n  </data>\n  <data name=\"WarningDialog_Text\" xml:space=\"preserve\">\n    <value>这是 Hosts 域名表文件编辑器。\n错误修改域名表可能会导致无法解析域名、访问网站，因此请谨慎使用。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"WarningDialog_Title\" xml:space=\"preserve\">\n    <value>警告</value>\n  </data>\n  <data name=\"WindowAdminTitle\" xml:space=\"preserve\">\n    <value>管理员权限: 域名表编辑器</value>\n    <comment>Title of the window when running as administrator. \"Hosts File Editor\" is the name of the utility. \"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"WindowTitle\" xml:space=\"preserve\">\n    <value>域名表编辑器</value>\n    <comment>Title of the window when running as user. \"Hosts File Editor\" is the name of the utility. \"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/MeasureTool/MeasureToolUI/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>  \n    <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n        <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n            <xsd:complexType>\n                <xsd:choice maxOccurs=\"unbounded\">\n                    <xsd:element name=\"data\">\n                        <xsd:complexType>\n                            <xsd:sequence>\n                                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n                            </xsd:sequence>\n                            <xsd:attribute name=\"name\" type=\"xsd:string\" msdata:Ordinal=\"1\" />\n                            <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n                            <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n                        </xsd:complexType>\n                    </xsd:element>\n                    <xsd:element name=\"resheader\">\n                        <xsd:complexType>\n                            <xsd:sequence>\n                                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                            </xsd:sequence>\n                            <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n                        </xsd:complexType>\n                    </xsd:element>\n                </xsd:choice>\n            </xsd:complexType>\n        </xsd:element>\n    </xsd:schema>\n    <resheader name=\"resmimetype\">\n        <value>text/microsoft-resx</value>\n    </resheader>\n    <resheader name=\"version\">\n        <value>1.3</value>\n    </resheader>\n    <resheader name=\"reader\">\n        <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n    </resheader>\n    <resheader name=\"writer\">\n        <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3500.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n    </resheader>\n    <data name=\"BtnBounds.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n        <value>框选 (Ctrl+1)</value>\n    </data>\n    <data name=\"BtnBoundsTooltip.Text\" xml:space=\"preserve\">\n        <value>框选 (Ctrl+1)</value>\n    </data>\n    <data name=\"BtnSpacing.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n        <value>间距 (Ctrl+2)</value>\n    </data>\n    <data name=\"BtnSpacingTooltip.Text\" xml:space=\"preserve\">\n        <value>间距 (Ctrl+2)</value>\n    </data>\n    <data name=\"BtnHorizontalSpacing.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n        <value>水平间距 (Ctrl+3)</value>\n    </data>\n    <data name=\"BtnHorizontalSpacingTooltip.Text\" xml:space=\"preserve\">\n        <value>水平间距 (Ctrl+3)</value>\n    </data>\n    <data name=\"BtnVerticalSpacing.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n        <value>垂直间距 (Ctrl+4)</value>\n    </data>\n    <data name=\"BtnVerticalSpacingTooltip.Text\" xml:space=\"preserve\">\n        <value>垂直间距 (Ctrl+4)</value>\n    </data>\n    <data name=\"BtnClosePanelTooltip.Text\" xml:space=\"preserve\">\n        <value>关闭 (Esc)</value>\n    </data>\n    <data name=\"MeasurementUnitAbbrPixel\" xml:space=\"preserve\">\n        <value>像素</value>\n    </data>\n    <data name=\"MeasurementUnitAbbrInch\" xml:space=\"preserve\">\n        <value>英寸</value>\n    </data>\n    <data name=\"MeasurementUnitAbbrCentimetre\" xml:space=\"preserve\">\n        <value>厘米</value>\n    </data>\n    <data name=\"MeasurementUnitAbbrMillimetre\" xml:space=\"preserve\">\n        <value>毫米</value>\n    </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Clipboard.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.IO.Compression;\nusing System.Linq;\nusing System.Net.Sockets;\nusing System.Runtime.InteropServices;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nusing Microsoft.PowerToys.Telemetry;\n\n// <summary>\n//     Clipboard related routines.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\nusing MouseWithoutBorders.Exceptions;\n\nusing SystemClipboard = System.Windows.Forms.Clipboard;\nusing Thread = MouseWithoutBorders.Core.Thread;\n\nnamespace MouseWithoutBorders\n{\n    internal partial class Common\n    {\n        internal static readonly char[] Comma = new char[] { ',' };\n        internal static readonly char[] Star = new char[] { '*' };\n        internal static readonly char[] NullSeparator = new char[] { '\\0' };\n\n        internal const uint BIG_CLIPBOARD_DATA_TIMEOUT = 60000; // [CN] 30s -> 60s\n        private const uint MAX_CLIPBOARD_DATA_SIZE_CAN_BE_SENT_INSTANTLY_TCP = 1024 * 1024; // 1MB\n        private const uint MAX_CLIPBOARD_FILE_SIZE_CAN_BE_SENT = 500 * 1024 * 1024; // 100MB [CN]-> 500MB\n        private const int TEXT_HEADER_SIZE = 12;\n        private const int DATA_SIZE = 48;\n        private const string TEXT_TYPE_SEP = \"{4CFF57F7-BEDD-43d5-AE8F-27A61E886F2F}\";\n        private static long lastClipboardEventTime;\n        private static string lastMachineWithClipboardData;\n        private static string lastDragDropFile;\n#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter\n        internal static long clipboardCopiedTime;\n#pragma warning restore SA1307\n\n        internal static ID LastIDWithClipboardData { get; set; }\n\n        internal static string LastDragDropFile\n        {\n            get => Common.lastDragDropFile;\n            set => Common.lastDragDropFile = value;\n        }\n\n        internal static string LastMachineWithClipboardData\n        {\n            get => Common.lastMachineWithClipboardData;\n            set => Common.lastMachineWithClipboardData = value;\n        }\n\n        internal static long LastClipboardEventTime\n        {\n            get => Common.lastClipboardEventTime;\n            set => Common.lastClipboardEventTime = value;\n        }\n\n        internal static IntPtr NextClipboardViewer { get; set; }\n\n        internal static bool IsClipboardDataImage { get; private set; }\n\n        internal static byte[] LastClipboardData { get; private set; }\n\n        private static object lastClipboardObject = string.Empty;\n\n        internal static bool HasSwitchedMachineSinceLastCopy { get; set; }\n\n        internal static bool CheckClipboardEx(ByteArrayOrString data, bool isFilePath)\n        {\n            Logger.LogDebug($\"{nameof(CheckClipboardEx)}: ShareClipboard = {Setting.Values.ShareClipboard}, TransferFile = {Setting.Values.TransferFile}, data = {data}.\");\n            Logger.LogDebug($\"{nameof(CheckClipboardEx)}: {nameof(Setting.Values.OneWayClipboardMode)} = {Setting.Values.OneWayClipboardMode}.\");\n\n            if (!Setting.Values.ShareClipboard)\n            {\n                return false;\n            }\n\n            if (Common.RunWithNoAdminRight && Setting.Values.OneWayClipboardMode)\n            {\n                return false;\n            }\n\n            if (GetTick() - LastClipboardEventTime < 1000)\n            {\n                Logger.LogDebug(\"GetTick() - lastClipboardEventTime < 1000\");\n                LastClipboardEventTime = GetTick();\n                return false;\n            }\n\n            LastClipboardEventTime = GetTick();\n\n            try\n            {\n                IsClipboardDataImage = false;\n                LastClipboardData = null;\n                LastDragDropFile = null;\n                GC.Collect();\n\n                string stringData = null;\n                byte[] byteData = null;\n\n                if (data.IsByteArray)\n                {\n                    byteData = data.GetByteArray();\n                }\n                else\n                {\n                    stringData = data.GetString();\n                }\n\n                if (stringData != null)\n                {\n                    if (!HasSwitchedMachineSinceLastCopy)\n                    {\n                        if (lastClipboardObject is string lastStringData && lastStringData.Equals(stringData, StringComparison.OrdinalIgnoreCase))\n                        {\n                            Logger.LogDebug(\"CheckClipboardEx: Same string data.\");\n                            return false;\n                        }\n                    }\n\n                    HasSwitchedMachineSinceLastCopy = false;\n\n                    if (isFilePath)\n                    {\n                        Logger.LogDebug(\"Clipboard contains FileDropList\");\n\n                        if (!Setting.Values.TransferFile)\n                        {\n                            Logger.LogDebug(\"TransferFile option is unchecked.\");\n                            return false;\n                        }\n\n                        string filePath = stringData;\n\n                        _ = Common.ImpersonateLoggedOnUserAndDoSomething(() =>\n                        {\n                            if (File.Exists(filePath) || Directory.Exists(filePath))\n                            {\n                                if (File.Exists(filePath) && new FileInfo(filePath).Length <= MAX_CLIPBOARD_FILE_SIZE_CAN_BE_SENT)\n                                {\n                                    Logger.LogDebug(\"Clipboard contains: \" + filePath);\n                                    LastDragDropFile = filePath;\n                                    SendClipboardBeat();\n                                    SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_BIG_CLIPBOARD, -1, ICON_BIG_CLIPBOARD, -1 });\n                                }\n                                else\n                                {\n                                    if (Directory.Exists(filePath))\n                                    {\n                                        Logger.LogDebug(\"Clipboard contains a directory: \" + filePath);\n                                        LastDragDropFile = filePath;\n                                        SendClipboardBeat();\n                                    }\n                                    else\n                                    {\n                                        LastDragDropFile = filePath + \" - 文件过大无法粘贴，请改为拖放文件！\";\n                                        SendClipboardBeat();\n                                        Logger.Log(\"Clipboard: File too big: \" + filePath);\n                                    }\n\n                                    SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_ERROR, -1, ICON_ERROR, -1 });\n                                }\n                            }\n                            else\n                            {\n                                Logger.Log(\"CheckClipboardEx: File not found: \" + filePath);\n                            }\n                        });\n                    }\n                    else\n                    {\n                        byte[] texts = Common.GetBytesU(stringData);\n\n                        using MemoryStream ms = new();\n                        using (DeflateStream s = new(ms, CompressionMode.Compress, true))\n                        {\n                            s.Write(texts, 0, texts.Length);\n                        }\n\n                        Logger.LogDebug(\"Plain/Zip = \" + texts.Length.ToString(CultureInfo.CurrentCulture) + \"/\" +\n                            ms.Length.ToString(CultureInfo.CurrentCulture));\n\n                        LastClipboardData = ms.GetBuffer();\n                    }\n                }\n                else if (byteData != null)\n                {\n                    if (!HasSwitchedMachineSinceLastCopy)\n                    {\n                        if (lastClipboardObject is byte[] lastByteData && Enumerable.SequenceEqual(lastByteData, byteData))\n                        {\n                            Logger.LogDebug(\"CheckClipboardEx: Same byte[] data.\");\n                            return false;\n                        }\n                    }\n\n                    HasSwitchedMachineSinceLastCopy = false;\n\n                    Logger.LogDebug(\"Clipboard contains image\");\n                    IsClipboardDataImage = true;\n                    LastClipboardData = byteData;\n                }\n                else\n                {\n                    Logger.LogDebug(\"*** Clipboard contains something else!\");\n                    return false;\n                }\n\n                lastClipboardObject = data;\n\n                if (LastClipboardData != null && LastClipboardData.Length > 0)\n                {\n                    if (LastClipboardData.Length > MAX_CLIPBOARD_DATA_SIZE_CAN_BE_SENT_INSTANTLY_TCP)\n                    {\n                        SendClipboardBeat();\n                        SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_BIG_CLIPBOARD, -1, ICON_BIG_CLIPBOARD, -1 });\n                    }\n                    else\n                    {\n                        SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_SMALL_CLIPBOARD, -1, -1, -1 });\n                        SendClipboardDataUsingTCP(LastClipboardData, IsClipboardDataImage);\n                    }\n\n                    return true;\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n\n            return false;\n        }\n\n        private static void SendClipboardDataUsingTCP(byte[] bytes, bool image)\n        {\n            if (Sk == null)\n            {\n                return;\n            }\n\n            new Task(() =>\n            {\n                // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n                // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n                using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n                System.Threading.Thread thread = Thread.CurrentThread;\n                thread.Name = $\"{nameof(SendClipboardDataUsingTCP)}.{thread.ManagedThreadId}\";\n                Thread.UpdateThreads(thread);\n                int l = bytes.Length;\n                int index = 0;\n                int len;\n                DATA package = new();\n                byte[] buf = new byte[PACKAGE_SIZE_EX];\n                int dataStart = PACKAGE_SIZE_EX - DATA_SIZE;\n\n                while (true)\n                {\n                    if ((index + DATA_SIZE) > l)\n                    {\n                        len = l - index;\n                        Array.Clear(buf, 0, PACKAGE_SIZE_EX);\n                    }\n                    else\n                    {\n                        len = DATA_SIZE;\n                    }\n\n                    Array.Copy(bytes, index, buf, dataStart, len);\n                    package.Bytes = buf;\n\n                    package.Type = image ? PackageType.ClipboardImage : PackageType.ClipboardText;\n                    package.Des = ID.ALL;\n                    SkSend(package, (uint)MachineID, false);\n\n                    index += DATA_SIZE;\n                    if (index >= l)\n                    {\n                        break;\n                    }\n                }\n\n                package.Type = PackageType.ClipboardDataEnd;\n                package.Des = ID.ALL;\n                SkSend(package, (uint)MachineID, false);\n            }).Start();\n        }\n\n        internal static void ReceiveClipboardDataUsingTCP(DATA data, bool image, TcpSk tcp)\n        {\n            try\n            {\n                if (Sk == null || RunOnLogonDesktop || RunOnScrSaverDesktop)\n                {\n                    return;\n                }\n\n                MemoryStream m = new();\n                int dataStart = PACKAGE_SIZE_EX - DATA_SIZE;\n                m.Write(data.Bytes, dataStart, DATA_SIZE);\n                int unexpectedCount = 0;\n\n                bool done = false;\n                do\n                {\n                    data = SocketStuff.TcpReceiveData(tcp, out int err);\n\n                    switch (data.Type)\n                    {\n                        case PackageType.ClipboardImage:\n                        case PackageType.ClipboardText:\n                            m.Write(data.Bytes, dataStart, DATA_SIZE);\n                            break;\n\n                        case PackageType.ClipboardDataEnd:\n                            done = true;\n                            break;\n\n                        default:\n                            Receiver.ProcessPackage(data, tcp);\n                            if (++unexpectedCount > 100)\n                            {\n                                Logger.Log(\"ReceiveClipboardDataUsingTCP: unexpectedCount > 100!\");\n                                done = true;\n                            }\n\n                            break;\n                    }\n                }\n                while (!done);\n\n                LastClipboardEventTime = GetTick();\n\n                if (image)\n                {\n                    Image im = Image.FromStream(m);\n                    Clipboard.SetImage(im);\n                    LastClipboardEventTime = GetTick();\n                }\n                else\n                {\n                    Common.SetClipboardData(m.GetBuffer());\n                    LastClipboardEventTime = GetTick();\n                }\n\n                m.Dispose();\n\n                SetToggleIcon(new int[TOGGLE_ICONS_SIZE] { ICON_SMALL_CLIPBOARD, -1, ICON_SMALL_CLIPBOARD, -1 });\n            }\n            catch (Exception e)\n            {\n                Logger.Log(\"ReceiveClipboardDataUsingTCP: \" + e.Message);\n            }\n        }\n\n        private static readonly Lock ClipboardThreadOldLock = new();\n        private static System.Threading.Thread clipboardThreadOld;\n\n        internal static void GetRemoteClipboard(string postAction)\n        {\n            if (!RunOnLogonDesktop && !RunOnScrSaverDesktop)\n            {\n                if (Common.LastMachineWithClipboardData == null ||\n                    Common.LastMachineWithClipboardData.Length < 1)\n                {\n                    return;\n                }\n\n                new Task(() =>\n                {\n                    // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n                    // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n                    using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n                    System.Threading.Thread thread = Thread.CurrentThread;\n                    thread.Name = $\"{nameof(ConnectAndGetData)}.{thread.ManagedThreadId}\";\n                    Thread.UpdateThreads(thread);\n                    ConnectAndGetData(postAction);\n                }).Start();\n            }\n        }\n\n        private static Stream m;\n\n        private static void ConnectAndGetData(object postAction)\n        {\n            if (Sk == null)\n            {\n                Logger.Log(\"ConnectAndGetData: Sk == null!\");\n                return;\n            }\n\n            string remoteMachine;\n            TcpClient clipboardTcpClient = null;\n            string postAct = (string)postAction;\n\n            Logger.LogDebug(\"ConnectAndGetData.postAction: \" + postAct);\n\n            ClipboardPostAction clipboardPostAct = postAct.Contains(\"mspaint,\") ? ClipboardPostAction.Mspaint\n                : postAct.Equals(\"desktop\", StringComparison.OrdinalIgnoreCase) ? ClipboardPostAction.Desktop\n                : ClipboardPostAction.Other;\n\n            try\n            {\n                remoteMachine = postAct.Contains(\"mspaint,\") ? postAct.Split(Comma)[1] : Common.LastMachineWithClipboardData;\n\n                remoteMachine = remoteMachine.Trim();\n\n                if (!IsConnectedByAClientSocketTo(remoteMachine))\n                {\n                    Logger.Log($\"No potential inbound connection from {MachineName} to {remoteMachine}, ask for a push back instead.\");\n                    ID machineId = MachinePool.ResolveID(remoteMachine);\n\n                    if (machineId != ID.NONE)\n                    {\n                        SkSend(\n                            new DATA()\n                            {\n                                Type = PackageType.ClipboardAsk,\n                                Des = machineId,\n                                MachineName = MachineName,\n                                PostAction = clipboardPostAct,\n                            },\n                            null,\n                            false);\n                    }\n                    else\n                    {\n                        Logger.Log($\"Unable to resolve {remoteMachine} to its long IP.\");\n                    }\n\n                    return;\n                }\n\n                ShowToolTip(\"正在连接 \" + remoteMachine, 2000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);\n\n                clipboardTcpClient = ConnectToRemoteClipboardSocket(remoteMachine);\n            }\n            catch (ThreadAbortException)\n            {\n                Logger.Log(\"The current thread is being aborted (1).\");\n                if (clipboardTcpClient != null && clipboardTcpClient.Connected)\n                {\n                    clipboardTcpClient.Client.Close();\n                }\n\n                return;\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n                Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]\n                {\n                    Common.ICON_BIG_CLIPBOARD,\n                    -1, Common.ICON_BIG_CLIPBOARD, -1,\n                });\n                ShowToolTip(e.Message, 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n                return;\n            }\n\n            bool clientPushData = false;\n\n            if (!ShakeHand(ref remoteMachine, clipboardTcpClient.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref clipboardPostAct))\n            {\n                return;\n            }\n\n            ReceiveAndProcessClipboardData(remoteMachine, clipboardTcpClient.Client, enStream, deStream, postAct);\n        }\n\n        internal static void ReceiveAndProcessClipboardData(string remoteMachine, Socket s, Stream enStream, Stream deStream, string postAct)\n        {\n            lock (ClipboardThreadOldLock)\n            {\n                // Do not enable two connections at the same time.\n                if (clipboardThreadOld != null && clipboardThreadOld.ThreadState != System.Threading.ThreadState.AbortRequested\n                    && clipboardThreadOld.ThreadState != System.Threading.ThreadState.Aborted && clipboardThreadOld.IsAlive\n                    && clipboardThreadOld.ManagedThreadId != Thread.CurrentThread.ManagedThreadId)\n                {\n                    if (clipboardThreadOld.Join(3000))\n                    {\n                        if (m != null)\n                        {\n                            m.Flush();\n                            m.Close();\n                            m = null;\n                        }\n                    }\n                }\n\n                clipboardThreadOld = Thread.CurrentThread;\n            }\n\n            try\n            {\n                byte[] header = new byte[1024];\n                byte[] buf = new byte[NETWORK_STREAM_BUF_SIZE];\n                string fileName = null;\n                string tempFile = \"data\", savingFolder = string.Empty;\n                Common.ToggleIconsIndex = 0;\n                int rv;\n                long receivedCount = 0;\n\n                if ((rv = deStream.ReadEx(header, 0, header.Length)) < header.Length)\n                {\n                    Logger.Log(\"Reading header failed: \" + rv.ToString(CultureInfo.CurrentCulture));\n                    Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]\n                    {\n                        Common.ICON_BIG_CLIPBOARD,\n                        -1, -1, -1,\n                    });\n                    return;\n                }\n\n                fileName = Common.GetStringU(header).Replace(\"\\0\", string.Empty);\n                Logger.LogDebug(\"Header: \" + fileName);\n                string[] headers = fileName.Split(Star);\n\n                if (headers.Length < 2 || !long.TryParse(headers[0], out long dataSize))\n                {\n                    Logger.Log(string.Format(\n                        CultureInfo.CurrentCulture,\n                        \"Reading header failed: {0}:{1}\",\n                        headers.Length,\n                        fileName));\n                    Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]\n                    {\n                        Common.ICON_BIG_CLIPBOARD,\n                        -1, -1, -1,\n                    });\n                    return;\n                }\n\n                fileName = headers[1];\n\n                Logger.LogDebug(string.Format(\n                    CultureInfo.CurrentCulture,\n                    \"Receiving {0}:{1} from {2}...\",\n                    Path.GetFileName(fileName),\n                    dataSize,\n                    remoteMachine));\n                ShowToolTip(\n                    string.Format(\n                        CultureInfo.CurrentCulture,\n                        \"正在从 {1} 接收 {0} ...\",\n                        Path.GetFileName(fileName),\n                        remoteMachine),\n                    5000,\n                    ToolTipIcon.Info,\n                    Setting.Values.ShowClipNetStatus);\n                if (fileName.StartsWith(\"image\", StringComparison.CurrentCultureIgnoreCase) ||\n                    fileName.StartsWith(\"text\", StringComparison.CurrentCultureIgnoreCase))\n                {\n                    m = new MemoryStream();\n                }\n                else\n                {\n                    if (postAct.Equals(\"desktop\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        _ = ImpersonateLoggedOnUserAndDoSomething(() =>\n                        {\n                            savingFolder = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + \"\\\\MouseWithoutBorders\\\\\";\n\n                            if (!Directory.Exists(savingFolder))\n                            {\n                                _ = Directory.CreateDirectory(savingFolder);\n                            }\n                        });\n\n                        tempFile = savingFolder + Path.GetFileName(fileName);\n                        m = new FileStream(tempFile, FileMode.Create);\n                    }\n                    else if (postAct.Contains(\"mspaint\"))\n                    {\n                        tempFile = GetMyStorageDir() + @\"ScreenCapture-\" +\n                            remoteMachine + \".png\";\n                        m = new FileStream(tempFile, FileMode.Create);\n                    }\n                    else\n                    {\n                        tempFile = GetMyStorageDir();\n                        tempFile += Path.GetFileName(fileName);\n                        m = new FileStream(tempFile, FileMode.Create);\n                    }\n\n                    Logger.Log(\"==> \" + tempFile);\n                }\n\n                ShowToolTip(\n                    string.Format(\n                        CultureInfo.CurrentCulture,\n                        \"正在从 {1} 接收 {0} ...\",\n                        Path.GetFileName(fileName),\n                        remoteMachine),\n                    5000,\n                    ToolTipIcon.Info,\n                    Setting.Values.ShowClipNetStatus);\n\n                do\n                {\n                    rv = deStream.ReadEx(buf, 0, buf.Length);\n\n                    if (rv > 0)\n                    {\n                        receivedCount += rv;\n\n                        if (receivedCount > dataSize)\n                        {\n                            rv -= (int)(receivedCount - dataSize);\n                        }\n\n                        m.Write(buf, 0, rv);\n                    }\n\n                    if (Common.ToggleIcons == null)\n                    {\n                        Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]\n                        {\n                                    Common.ICON_SMALL_CLIPBOARD,\n                                    -1, Common.ICON_SMALL_CLIPBOARD, -1,\n                        });\n                    }\n\n                    string text = string.Format(CultureInfo.CurrentCulture, \"{0}KB received: {1}\", m.Length / 1024, Path.GetFileName(fileName));\n\n                    DoSomethingInUIThread(() =>\n                    {\n                        MainForm.SetTrayIconText(text);\n                    });\n                }\n                while (rv > 0);\n\n                if (m != null && fileName != null)\n                {\n                    m.Flush();\n                    Logger.LogDebug(m.Length.ToString(CultureInfo.CurrentCulture) + \" bytes received.\");\n                    Common.LastClipboardEventTime = Common.GetTick();\n                    string toolTipText = null;\n                    string sizeText = m.Length >= 1024\n                        ? (m.Length / 1024).ToString(CultureInfo.CurrentCulture) + \"KB\"\n                        : m.Length.ToString(CultureInfo.CurrentCulture) + \"Bytes\";\n\n                    PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersClipboardFileTransferEvent());\n\n                    if (fileName.StartsWith(\"image\", StringComparison.CurrentCultureIgnoreCase))\n                    {\n                        Clipboard.SetImage(Image.FromStream(m));\n                        toolTipText = string.Format(\n                            CultureInfo.CurrentCulture,\n                            \"{0} {1} 来自 {2} 已存入剪贴板.\",\n                            sizeText,\n                            \"image\",\n                            remoteMachine);\n                    }\n                    else if (fileName.StartsWith(\"text\", StringComparison.CurrentCultureIgnoreCase))\n                    {\n                        byte[] data = (m as MemoryStream).GetBuffer();\n                        toolTipText = string.Format(\n                            CultureInfo.CurrentCulture,\n                            \"{0} {1} 来自 {2} 已存入剪贴板.\",\n                            sizeText,\n                            \"text\",\n                            remoteMachine);\n                        Common.SetClipboardData(data);\n                    }\n                    else if (tempFile != null)\n                    {\n                        if (postAct.Equals(\"desktop\", StringComparison.OrdinalIgnoreCase))\n                        {\n                            toolTipText = string.Format(\n                                CultureInfo.CurrentCulture,\n                                \"{0} {1} 来自 {2}!\",\n                                sizeText,\n                                Path.GetFileName(fileName),\n                                remoteMachine);\n\n                            _ = ImpersonateLoggedOnUserAndDoSomething(() =>\n                            {\n                                ProcessStartInfo startInfo = new();\n                                startInfo.UseShellExecute = true;\n                                startInfo.WorkingDirectory = savingFolder;\n                                startInfo.FileName = savingFolder;\n                                startInfo.Verb = \"open\";\n                                _ = Process.Start(startInfo);\n                            });\n                        }\n                        else if (postAct.Contains(\"mspaint\"))\n                        {\n                            m.Close();\n                            m = null;\n                            OpenImage(tempFile);\n                            toolTipText = string.Format(\n                                CultureInfo.CurrentCulture,\n                                \"{0} {1} 来自 {2} 已放入画图.\",\n                                sizeText,\n                                Path.GetFileName(tempFile),\n                                remoteMachine);\n                        }\n                        else\n                        {\n                            StringCollection filePaths = new()\n                            {\n                                tempFile,\n                            };\n                            Clipboard.SetFileDropList(filePaths);\n                            toolTipText = string.Format(\n                                CultureInfo.CurrentCulture,\n                                \"{0} {1} 来自 {2} 已存入剪贴板.\",\n                                sizeText,\n                                Path.GetFileName(fileName),\n                                remoteMachine);\n                        }\n                    }\n\n                    if (!string.IsNullOrWhiteSpace(toolTipText))\n                    {\n                        Common.ShowToolTip(toolTipText, 5000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);\n                    }\n\n                    DoSomethingInUIThread(() =>\n                    {\n                        MainForm.UpdateNotifyIcon();\n                    });\n\n                    m?.Close();\n                    m = null;\n                }\n            }\n            catch (ThreadAbortException)\n            {\n                Logger.Log(\"The current thread is being aborted (3).\");\n                s.Close();\n\n                if (m != null)\n                {\n                    m.Close();\n                    m = null;\n                }\n\n                return;\n            }\n            catch (Exception e)\n            {\n                if (e is IOException)\n                {\n                    string log = $\"{nameof(ReceiveAndProcessClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                    Logger.Log(log);\n                }\n                else\n                {\n                    Logger.Log(e);\n                }\n\n                Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]\n                {\n                    Common.ICON_BIG_CLIPBOARD,\n                    -1, Common.ICON_BIG_CLIPBOARD, -1,\n                });\n                ShowToolTip(e.Message, 1000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);\n\n                if (m != null)\n                {\n                    m.Close();\n                    m = null;\n                }\n\n                return;\n            }\n\n            s.Close();\n        }\n\n        internal static bool ShakeHand(ref string remoteName, Socket s, out Stream enStream, out Stream deStream, ref bool clientPushData, ref ClipboardPostAction postAction)\n        {\n            const int CLIPBOARD_HANDSHAKE_TIMEOUT = 30;\n            s.ReceiveTimeout = CLIPBOARD_HANDSHAKE_TIMEOUT * 1000;\n            s.NoDelay = true;\n            s.SendBufferSize = s.ReceiveBufferSize = 1024000;\n\n            bool handShaken = false;\n            enStream = deStream = null;\n\n            try\n            {\n                DATA package = new()\n                {\n                    Type = clientPushData ? PackageType.ClipboardPush : PackageType.Clipboard,\n                    PostAction = postAction,\n                    Src = MachineID,\n                    MachineName = MachineName,\n                };\n\n                byte[] buf = new byte[PACKAGE_SIZE_EX];\n\n                NetworkStream ns = new(s);\n                enStream = Common.GetEncryptedStream(ns);\n                Common.SendOrReceiveARandomDataBlockPerInitialIV(enStream);\n                Logger.LogDebug($\"{nameof(ShakeHand)}: Writing header package.\");\n                enStream.Write(package.Bytes, 0, PACKAGE_SIZE_EX);\n\n                Logger.LogDebug($\"{nameof(ShakeHand)}: Sent: clientPush={clientPushData}, postAction={postAction}.\");\n\n                deStream = Common.GetDecryptedStream(ns);\n                Common.SendOrReceiveARandomDataBlockPerInitialIV(deStream, false);\n\n                Logger.LogDebug($\"{nameof(ShakeHand)}: Reading header package.\");\n\n                int bytesReceived = deStream.ReadEx(buf, 0, Common.PACKAGE_SIZE_EX);\n                package.Bytes = buf;\n\n                string name = \"Unknown\";\n\n                if (bytesReceived == Common.PACKAGE_SIZE_EX)\n                {\n                    if (package.Type is PackageType.Clipboard or PackageType.ClipboardPush)\n                    {\n                        name = remoteName = package.MachineName;\n\n                        Logger.LogDebug($\"{nameof(ShakeHand)}: Connection from {name}:{package.Src}\");\n\n                        if (Common.MachinePool.ResolveID(name) == package.Src && Common.IsConnectedTo(package.Src))\n                        {\n                            clientPushData = package.Type == PackageType.ClipboardPush;\n                            postAction = package.PostAction;\n                            handShaken = true;\n                            Logger.LogDebug($\"{nameof(ShakeHand)}: Received: clientPush={clientPushData}, postAction={postAction}.\");\n                        }\n                        else\n                        {\n                            Logger.LogDebug($\"{nameof(ShakeHand)}: No active connection to the machine: {name}.\");\n                        }\n                    }\n                    else\n                    {\n                        Logger.LogDebug($\"{nameof(ShakeHand)}: Unexpected package type: {package.Type}.\");\n                    }\n                }\n                else\n                {\n                    Logger.LogDebug($\"{nameof(ShakeHand)}: BytesTransferred != PACKAGE_SIZE_EX: {bytesReceived}\");\n                }\n\n                if (!handShaken)\n                {\n                    string msg = $\"剪贴板连接被拒绝: {name}:{remoteName}/{package.Src}\\r\\n\\r\\n请确保软件版本相同.\";\n                    Logger.Log(msg);\n                    Common.ShowToolTip(msg, 3000, ToolTipIcon.Warning);\n                    Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE] { Common.ICON_BIG_CLIPBOARD, -1, -1, -1 });\n                }\n            }\n            catch (ThreadAbortException)\n            {\n                Logger.Log($\"{nameof(ShakeHand)}: The current thread is being aborted.\");\n                s.Close();\n            }\n            catch (Exception e)\n            {\n                if (e is IOException)\n                {\n                    string log = $\"{nameof(ShakeHand)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                    Logger.Log(log);\n                }\n                else\n                {\n                    Logger.Log(e);\n                }\n\n                Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE]\n                {\n                    Common.ICON_BIG_CLIPBOARD,\n                    -1, Common.ICON_BIG_CLIPBOARD, -1,\n                });\n                MainForm.UpdateNotifyIcon();\n                ShowToolTip(e.Message + \"\\r\\n\\r\\n请确保软件版本相同.\", 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n\n                if (m != null)\n                {\n                    m.Close();\n                    m = null;\n                }\n            }\n\n            return handShaken;\n        }\n\n        internal static TcpClient ConnectToRemoteClipboardSocket(string remoteMachine)\n        {\n            TcpClient clipboardTcpClient;\n            clipboardTcpClient = new TcpClient(AddressFamily.InterNetworkV6);\n            clipboardTcpClient.Client.DualMode = true;\n\n            SocketStuff sk = Common.Sk;\n\n            if (sk != null)\n            {\n                Common.DoSomethingInUIThread(() => Common.MainForm.ChangeIcon(Common.ICON_SMALL_CLIPBOARD));\n\n                System.Net.IPAddress ip = GetConnectedClientSocketIPAddressFor(remoteMachine);\n                Logger.LogDebug($\"{nameof(ConnectToRemoteClipboardSocket)}Connecting to {remoteMachine}:{ip}:{sk.TcpPort}...\");\n\n                if (ip != null)\n                {\n                    clipboardTcpClient.Connect(ip, sk.TcpPort);\n                }\n                else\n                {\n                    clipboardTcpClient.Connect(remoteMachine, sk.TcpPort);\n                }\n\n                Logger.LogDebug($\"Connected from {clipboardTcpClient.Client.LocalEndPoint}. Getting data...\");\n                return clipboardTcpClient;\n            }\n            else\n            {\n                throw new ExpectedSocketException($\"{nameof(ConnectToRemoteClipboardSocket)}: No longer connected.\");\n            }\n        }\n\n        internal static void SetClipboardData(byte[] data)\n        {\n            if (data == null || data.Length <= 0)\n            {\n                Logger.Log(\"data is null or empty!\");\n                return;\n            }\n\n            if (data.Length > 1024000)\n            {\n                ShowToolTip(\n                    string.Format(\n                        CultureInfo.CurrentCulture,\n                        \"正在解压 {0} 剪贴板数据 ...\",\n                        (data.Length / 1024).ToString(CultureInfo.CurrentCulture) + \"KB\"),\n                    5000,\n                    ToolTipIcon.Info,\n                    Setting.Values.ShowClipNetStatus);\n            }\n\n            string st = string.Empty;\n\n            using (MemoryStream ms = new(data))\n            {\n                using DeflateStream s = new(ms, CompressionMode.Decompress, true);\n                const int BufferSize = 1024000; // Buffer size should be big enough, this is critical to performance!\n\n                int rv = 0;\n\n                do\n                {\n                    byte[] buffer = new byte[BufferSize];\n                    rv = s.ReadEx(buffer, 0, BufferSize);\n\n                    if (rv > 0)\n                    {\n                        st += Common.GetStringU(buffer);\n                    }\n                    else\n                    {\n                        break;\n                    }\n                }\n                while (true);\n            }\n\n            int textTypeCount = 0;\n            string[] texts = st.Split(new string[] { TEXT_TYPE_SEP }, StringSplitOptions.RemoveEmptyEntries);\n            string tmp;\n            DataObject data1 = new();\n\n            foreach (string txt in texts)\n            {\n                if (string.IsNullOrEmpty(txt.Trim(NullSeparator)))\n                {\n                    continue;\n                }\n\n                tmp = txt[3..];\n\n                if (txt.StartsWith(\"RTF\", StringComparison.CurrentCultureIgnoreCase))\n                {\n                    Logger.LogDebug(((double)tmp.Length / 1024).ToString(\"0.00\", CultureInfo.InvariantCulture) + \"KB of RTF <-\");\n                    data1.SetData(DataFormats.Rtf, tmp);\n                }\n                else if (txt.StartsWith(\"HTM\", StringComparison.CurrentCultureIgnoreCase))\n                {\n                    Logger.LogDebug(((double)tmp.Length / 1024).ToString(\"0.00\", CultureInfo.InvariantCulture) + \"KB of HTM <-\");\n                    data1.SetData(DataFormats.Html, tmp);\n                }\n                else if (txt.StartsWith(\"TXT\", StringComparison.CurrentCultureIgnoreCase))\n                {\n                    Logger.LogDebug(((double)tmp.Length / 1024).ToString(\"0.00\", CultureInfo.InvariantCulture) + \"KB of TXT <-\");\n                    data1.SetData(DataFormats.UnicodeText, tmp);\n                }\n                else\n                {\n                    if (textTypeCount == 0)\n                    {\n                        Logger.LogDebug(((double)txt.Length / 1024).ToString(\"0.00\", CultureInfo.InvariantCulture) + \"KB of UNI <-\");\n                        data1.SetData(DataFormats.UnicodeText, txt);\n                    }\n\n                    Logger.Log(\"Invalid clipboard format received!\");\n                }\n\n                textTypeCount++;\n            }\n\n            if (textTypeCount > 0)\n            {\n                Clipboard.SetDataObject(data1);\n            }\n        }\n    }\n\n    internal static class Clipboard\n    {\n        public static void SetFileDropList(StringCollection filePaths)\n        {\n            Common.DoSomethingInUIThread(() =>\n            {\n                try\n                {\n                    _ = Common.Retry(\n                        nameof(SystemClipboard.SetFileDropList),\n                        () =>\n                        {\n                            SystemClipboard.SetFileDropList(filePaths);\n                            return true;\n                        },\n                        (log) => Logger.TelemetryLogTrace(\n                            log,\n                            SeverityLevel.Information),\n                        () => Common.LastClipboardEventTime = Common.GetTick());\n                }\n                catch (ExternalException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ThreadStateException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ArgumentNullException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ArgumentException e)\n                {\n                    Logger.Log(e);\n                }\n            });\n        }\n\n        public static void SetImage(Image image)\n        {\n            Common.DoSomethingInUIThread(() =>\n            {\n                try\n                {\n                    _ = Common.Retry(\n                        nameof(SystemClipboard.SetImage),\n                        () =>\n                    {\n                        SystemClipboard.SetImage(image);\n                        return true;\n                    },\n                        (log) => Logger.TelemetryLogTrace(log, SeverityLevel.Information),\n                        () => Common.LastClipboardEventTime = Common.GetTick());\n                }\n                catch (ExternalException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ThreadStateException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ArgumentNullException e)\n                {\n                    Logger.Log(e);\n                }\n            });\n        }\n\n        public static void SetText(string text)\n        {\n            Common.DoSomethingInUIThread(() =>\n            {\n                try\n                {\n                    _ = Common.Retry(\n                        nameof(SystemClipboard.SetText),\n                        () =>\n                    {\n                        SystemClipboard.SetText(text);\n                        return true;\n                    },\n                        (log) => Logger.TelemetryLogTrace(log, SeverityLevel.Information),\n                        () => Common.LastClipboardEventTime = Common.GetTick());\n                }\n                catch (ExternalException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ThreadStateException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ArgumentNullException e)\n                {\n                    Logger.Log(e);\n                }\n            });\n        }\n\n        public static void SetDataObject(DataObject dataObject)\n        {\n            Common.DoSomethingInUIThread(() =>\n            {\n                try\n                {\n                    SystemClipboard.SetDataObject(dataObject, true, 10, 200);\n                }\n                catch (ExternalException e)\n                {\n                    string dataFormats = string.Join(\",\", dataObject.GetFormats());\n                    Logger.Log($\"{e.Message}: {dataFormats}\");\n                }\n                catch (ThreadStateException e)\n                {\n                    Logger.Log(e);\n                }\n                catch (ArgumentNullException e)\n                {\n                    Logger.Log(e);\n                }\n            });\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Encryption.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\n// <summary>\n//     Encrypt/decrypt implementation.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing System;\nusing System.Collections.Concurrent;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Security.Cryptography;\nusing System.Threading.Tasks;\n\nusing MouseWithoutBorders.Core;\n\nnamespace MouseWithoutBorders\n{\n    internal partial class Common\n    {\n#pragma warning disable SYSLIB0021\n        private static AesCryptoServiceProvider symAl;\n#pragma warning restore SYSLIB0021\n#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter\n        internal static string myKey;\n#pragma warning restore SA1307\n        private static uint magicNumber;\n        private static Random ran = new(); // Used for non encryption related functionality.\n        internal const int SymAlBlockSize = 16;\n\n        /// <summary>\n        /// This is used for the first encryption block, the following blocks will be combined with the cipher text of the previous block.\n        /// Thus identical blocks in the socket stream would be encrypted to different cipher text blocks.\n        /// The first block is a handshake one containing random data.\n        /// Related Unit Test: TestEncryptDecrypt\n        /// </summary>\n        internal static readonly string InitialIV = ulong.MaxValue.ToString(CultureInfo.InvariantCulture);\n\n        internal static Random Ran\n        {\n            get => Common.ran ??= new Random();\n            set => Common.ran = value;\n        }\n\n        internal static uint MagicNumber\n        {\n            get => Common.magicNumber;\n            set => Common.magicNumber = value;\n        }\n\n        internal static string MyKey\n        {\n            get => Common.myKey;\n\n            set\n            {\n                if (Common.myKey != value)\n                {\n                    Common.myKey = value;\n                    _ = Task.Factory.StartNew(\n                        () => Common.GenLegalKey(),\n                        System.Threading.CancellationToken.None,\n                        TaskCreationOptions.None,\n                        TaskScheduler.Default); // Cache the key to improve UX.\n                }\n            }\n        }\n\n        internal static string KeyDisplayedText(string key)\n        {\n            string displayedValue = string.Empty;\n            int i = 0;\n\n            do\n            {\n                int length = Math.Min(4, key.Length - i);\n                displayedValue += string.Concat(key.AsSpan(i, length), \"  \");\n                i += 4;\n            }\n            while (i < key.Length - 1);\n\n            return displayedValue.Trim();\n        }\n\n        internal static bool GeneratedKey { get; set; }\n\n        internal static bool KeyCorrupted { get; set; }\n\n        internal static void InitEncryption()\n        {\n            try\n            {\n                if (symAl == null)\n                {\n#pragma warning disable SYSLIB0021 // No proper replacement for now\n                    symAl = new AesCryptoServiceProvider();\n#pragma warning restore SYSLIB0021\n                    symAl.KeySize = 256;\n                    symAl.BlockSize = SymAlBlockSize * 8;\n                    symAl.Padding = PaddingMode.Zeros;\n                    symAl.Mode = CipherMode.CBC;\n                    symAl.GenerateIV();\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        private static readonly ConcurrentDictionary<string, byte[]> LegalKeyDictionary = new(StringComparer.OrdinalIgnoreCase);\n\n        internal static byte[] GenLegalKey()\n        {\n            byte[] rv;\n            string myKey = Common.MyKey;\n\n            if (!LegalKeyDictionary.TryGetValue(myKey, out byte[] value))\n            {\n                Rfc2898DeriveBytes key = new(\n                    myKey,\n                    Common.GetBytesU(InitialIV),\n                    50000,\n                    HashAlgorithmName.SHA512);\n                rv = key.GetBytes(32);\n                _ = LegalKeyDictionary.AddOrUpdate(myKey, rv, (k, v) => rv);\n            }\n            else\n            {\n                rv = value;\n            }\n\n            return rv;\n        }\n\n        private static byte[] GenLegalIV()\n        {\n            string st = InitialIV;\n            int ivLength = symAl.IV.Length;\n            if (st.Length > ivLength)\n            {\n                st = st[..ivLength];\n            }\n            else if (st.Length < ivLength)\n            {\n                st = st.PadRight(ivLength, ' ');\n            }\n\n            return GetBytes(st);\n        }\n\n        internal static Stream GetEncryptedStream(Stream encryptedStream)\n        {\n            ICryptoTransform encryptor;\n            encryptor = symAl.CreateEncryptor(GenLegalKey(), GenLegalIV());\n            return new CryptoStream(encryptedStream, encryptor, CryptoStreamMode.Write);\n        }\n\n        internal static Stream GetDecryptedStream(Stream encryptedStream)\n        {\n            ICryptoTransform decryptor;\n            decryptor = symAl.CreateDecryptor(GenLegalKey(), GenLegalIV());\n            return new CryptoStream(encryptedStream, decryptor, CryptoStreamMode.Read);\n        }\n\n        internal static uint Get24BitHash(string st)\n        {\n            if (string.IsNullOrEmpty(st))\n            {\n                return 0;\n            }\n\n            byte[] bytes = new byte[PACKAGE_SIZE];\n            for (int i = 0; i < PACKAGE_SIZE; i++)\n            {\n                if (i < st.Length)\n                {\n                    bytes[i] = (byte)st[i];\n                }\n            }\n\n            var hash = SHA512.Create();\n            byte[] hashValue = hash.ComputeHash(bytes);\n\n            for (int i = 0; i < 50000; i++)\n            {\n                hashValue = hash.ComputeHash(hashValue);\n            }\n\n            Logger.LogDebug(string.Format(CultureInfo.CurrentCulture, \"magic: {0},{1},{2}\", hashValue[0], hashValue[1], hashValue[^1]));\n            hash.Clear();\n            return (uint)((hashValue[0] << 23) + (hashValue[1] << 16) + (hashValue[^1] << 8) + hashValue[2]);\n        }\n\n        internal static string GetDebugInfo(string st)\n        {\n            return string.IsNullOrEmpty(st) ? st : ((byte)(Common.GetBytesU(st).Sum(value => value) % 256)).ToString(CultureInfo.InvariantCulture);\n        }\n\n        internal static string CreateDefaultKey()\n        {\n            return CreateRandomKey();\n        }\n\n        private const int PW_LENGTH = 16;\n\n        public static string CreateRandomKey()\n        {\n            // Not including characters like \"'`O0& since they are confusing to users.\n            string[] chars = new[] { \"abcdefghjkmnpqrstuvxyz\", \"ABCDEFGHJKMNPQRSTUVXYZ\", \"123456789\", \"~!@#$%^*()_-+=:;<,>.?/\\\\|[]\" };\n            char[][] charactersUsedForKey = chars.Select(charset => Enumerable.Range(0, charset.Length - 1).Select(i => charset[i]).ToArray()).ToArray();\n            byte[] randomData = new byte[1];\n            string key = string.Empty;\n\n            do\n            {\n                foreach (string set in chars)\n                {\n                    randomData = RandomNumberGenerator.GetBytes(1);\n                    key += set[randomData[0] % set.Length];\n\n                    if (key.Length >= PW_LENGTH)\n                    {\n                        break;\n                    }\n                }\n            }\n            while (key.Length < PW_LENGTH);\n\n            return key;\n        }\n\n        internal static bool IsKeyValid(string key, out string error)\n        {\n            error = string.IsNullOrEmpty(key) || key.Length < 16\n                ? \"密码必须至少包含 16 个字符，空格不计，必须由程序自动生成。\"\n                : null;\n\n            return error == null;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Event.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Drawing;\nusing System.Globalization;\nusing System.Threading;\nusing System.Threading.Tasks;\n\n// <summary>\n//     Keyboard/Mouse hook callback implementation.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\nusing MouseWithoutBorders.Form;\n\nusing Thread = MouseWithoutBorders.Core.Thread;\n\nnamespace MouseWithoutBorders\n{\n    internal partial class Common\n    {\n        private static readonly DATA KeybdPackage = new();\n        private static readonly DATA MousePackage = new();\n#pragma warning disable SA1307 // Accessible fields should begin with upper-case names\n        internal static ulong inputEventCount;\n        internal static ulong invalidPackageCount;\n#pragma warning restore SA1307\n        internal static int MOVE_MOUSE_RELATIVE = 100000;\n        internal static int XY_BY_PIXEL = 300000;\n\n        static Common()\n        {\n        }\n\n        internal static ulong InvalidPackageCount\n        {\n            get => Common.invalidPackageCount;\n            set => Common.invalidPackageCount = value;\n        }\n\n        internal static ulong InputEventCount\n        {\n            get => Common.inputEventCount;\n            set => Common.inputEventCount = value;\n        }\n\n        internal static ulong RealInputEventCount\n        {\n            get;\n            set;\n        }\n\n        private static Point actualLastPos;\n        private static int myLastX;\n        private static int myLastY;\n\n        [SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification = \"Dotnet port with style preservation\")]\n        internal static void MouseEvent(MOUSEDATA e, int dx, int dy)\n        {\n            try\n            {\n                PaintCount = 0;\n                bool switchByMouseEnabled = IsSwitchingByMouseEnabled();\n\n                if (switchByMouseEnabled && Sk != null && (DesMachineID == MachineID || !Setting.Values.MoveMouseRelatively) && e.dwFlags == WM_MOUSEMOVE)\n                {\n                    Point p = MoveToMyNeighbourIfNeeded(e.X, e.Y, desMachineID);\n\n                    if (!p.IsEmpty)\n                    {\n                        HasSwitchedMachineSinceLastCopy = true;\n\n                        Logger.LogDebug(string.Format(\n                            CultureInfo.CurrentCulture,\n                            \"***** Host Machine: newDesMachineIdEx set = [{0}]. Mouse is now at ({1},{2})\",\n                            newDesMachineIdEx,\n                            e.X,\n                            e.Y));\n\n                        myLastX = e.X;\n                        myLastY = e.Y;\n\n                        PrepareToSwitchToMachine(newDesMachineIdEx, p);\n                    }\n                }\n\n                if (desMachineID != MachineID && SwitchLocation.Count <= 0)\n                {\n                    MousePackage.Des = desMachineID;\n                    MousePackage.Type = PackageType.Mouse;\n                    MousePackage.Md.dwFlags = e.dwFlags;\n                    MousePackage.Md.WheelDelta = e.WheelDelta;\n\n                    // Relative move\n                    if (Setting.Values.MoveMouseRelatively && Math.Abs(dx) >= MOVE_MOUSE_RELATIVE && Math.Abs(dy) >= MOVE_MOUSE_RELATIVE)\n                    {\n                        MousePackage.Md.X = dx;\n                        MousePackage.Md.Y = dy;\n                    }\n                    else\n                    {\n                        MousePackage.Md.X = (e.X - primaryScreenBounds.Left) * 65535 / screenWidth;\n                        MousePackage.Md.Y = (e.Y - primaryScreenBounds.Top) * 65535 / screenHeight;\n                    }\n\n                    SkSend(MousePackage, null, false);\n\n                    if (MousePackage.Md.dwFlags is WM_LBUTTONUP or WM_RBUTTONUP)\n                    {\n                        Thread.Sleep(10);\n                    }\n\n                    NativeMethods.GetCursorPos(ref actualLastPos);\n\n                    if (actualLastPos != Common.LastPos)\n                    {\n                        Logger.LogDebug($\"Mouse cursor has moved unexpectedly: Expected: {Common.LastPos}, actual: {actualLastPos}.\");\n                        Common.LastPos = actualLastPos;\n                    }\n                }\n\n#if SHOW_ON_WINLOGON_EX\n                if (RunOnLogonDesktop && e.dwFlags == WM_RBUTTONUP &&\n                    desMachineID == machineID &&\n                    e.x > 2 && e.x < 100 && e.y > 2 && e.y < 20)\n                {\n                    DoSomethingInUIThread(delegate()\n                    {\n                        MainForm.HideMenuWhenRunOnLogonDesktop();\n                        MainForm.MainMenu.Hide();\n                        MainForm.MainMenu.Show(e.x - 5, e.y - 3);\n                    });\n                }\n#endif\n            }\n            catch (Exception ex)\n            {\n                Logger.Log(ex);\n            }\n        }\n\n        internal static bool IsSwitchingByMouseEnabled()\n        {\n            return (EasyMouseOption)Setting.Values.EasyMouse == EasyMouseOption.开启 || InputHook.EasyMouseKeyDown;\n        }\n\n        internal static void PrepareToSwitchToMachine(ID newDesMachineID, Point desMachineXY)\n        {\n            Logger.LogDebug($\"PrepareToSwitchToMachine: newDesMachineID = {newDesMachineID}, desMachineXY = {desMachineXY}\");\n\n            if (((GetTick() - lastJump < 100) && (GetTick() - lastJump > 0)) || desMachineID == ID.ALL)\n            {\n                Logger.LogDebug(\"PrepareToSwitchToMachine: lastJump\");\n                return;\n            }\n\n            lastJump = GetTick();\n\n            string newDesMachineName = NameFromID(newDesMachineID);\n\n            if (!IsConnectedTo(newDesMachineID))\n            {// Connection lost, cancel switching\n                Logger.LogDebug(\"No active connection found for \" + newDesMachineName);\n\n                // ShowToolTip(\"No active connection found for [\" + newDesMachineName + \"]!\", 500);\n            }\n            else\n            {\n                Common.newDesMachineID = newDesMachineID;\n                SwitchLocation.X = desMachineXY.X;\n                SwitchLocation.Y = desMachineXY.Y;\n                SwitchLocation.ResetCount();\n                _ = EvSwitch.Set();\n\n                // PostMessage(mainForm.Handle, WM_SWITCH, IntPtr.Zero, IntPtr.Zero);\n                if (newDesMachineID != DragMachine)\n                {\n                    if (!IsDragging && !IsDropping)\n                    {\n                        if (MouseDown && !RunOnLogonDesktop && !RunOnScrSaverDesktop)\n                        {\n                            DragDropStep02();\n                        }\n                    }\n                    else if (DragMachine != (ID)1)\n                    {\n                        ChangeDropMachine();\n                    }\n                }\n                else\n                {\n                    DragDropStep11();\n                }\n\n                // Change des machine\n                if (desMachineID != newDesMachineID)\n                {\n                    Logger.LogDebug(\"MouseEvent: Switching to new machine:\" + newDesMachineName);\n\n                    // Ask current machine to hide the Mouse cursor\n                    if (newDesMachineID != ID.ALL && desMachineID != MachineID)\n                    {\n                        SendPackage(desMachineID, PackageType.HideMouse);\n                    }\n\n                    DesMachineID = newDesMachineID;\n\n                    if (desMachineID == MachineID)\n                    {\n                        if (GetTick() - clipboardCopiedTime < BIG_CLIPBOARD_DATA_TIMEOUT)\n                        {\n                            clipboardCopiedTime = 0;\n                            Common.GetRemoteClipboard(\"PrepareToSwitchToMachine\");\n                        }\n                    }\n                    else\n                    {\n                        // Ask the new active machine to get clipboard data (if the data is too big)\n                        SendPackage(desMachineID, PackageType.MachineSwitched);\n                    }\n\n                    _ = Interlocked.Increment(ref switchCount);\n                }\n            }\n        }\n\n        internal static void SaveSwitchCount()\n        {\n            if (SwitchCount > 0)\n            {\n                _ = Task.Run(() =>\n                {\n                    Setting.Values.SwitchCount += SwitchCount;\n                    _ = Interlocked.Exchange(ref switchCount, 0);\n                });\n            }\n        }\n\n        internal static void KeybdEvent(KEYBDDATA e)\n        {\n            try\n            {\n                PaintCount = 0;\n                if (desMachineID != newDesMachineID)\n                {\n                    Logger.LogDebug(\"KeybdEvent: Switching to new machine...\");\n                    DesMachineID = newDesMachineID;\n                }\n\n                if (desMachineID != MachineID)\n                {\n                    KeybdPackage.Des = desMachineID;\n                    KeybdPackage.Type = PackageType.Keyboard;\n                    KeybdPackage.Kd = e;\n                    KeybdPackage.DateTime = GetTick();\n                    SkSend(KeybdPackage, null, false);\n                    if (KeybdPackage.Kd.dwFlags is WM_KEYUP or WM_SYSKEYUP)\n                    {\n                        Thread.Sleep(10);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Logger.Log(ex);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Helper.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Security.Principal;\nusing System.Windows.Forms;\n\n// <summary>\n//     Some other helper methods.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing Microsoft.Win32;\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\nusing static System.Windows.Forms.Control;\n\nnamespace MouseWithoutBorders\n{\n    internal partial class Common\n    {\n        internal const string HELPER_FORM_TEXT = \"Mouse without Borders Helper\";\n        internal const string HelperProcessName = \"PowerToys.MouseWithoutBordersHelper\";\n        private static bool signalHelperToExit;\n        private static bool signalWatchDogToExit;\n        internal static long WndProcCounter;\n\n        private static void WatchDogThread()\n        {\n            long oldCounter = WndProcCounter;\n\n            do\n            {\n                for (int i = 0; i < 10; i++)\n                {\n                    Thread.Sleep(1000);\n\n                    if (signalWatchDogToExit)\n                    {\n                        break;\n                    }\n                }\n\n                while (BlockingUI)\n                {\n                    Thread.Sleep(1000);\n                }\n\n                if (WndProcCounter == oldCounter)\n                {\n                    Process p = Process.GetCurrentProcess();\n                    string procInfo = $\"{p.PrivateMemorySize64 / 1024 / 1024}MB, {p.TotalProcessorTime}, {Environment.ProcessorCount}.\";\n                    string threadStacks = $\"{procInfo} {Thread.DumpThreadsStack()}\";\n                    Logger.TelemetryLogTrace(threadStacks, SeverityLevel.Error);\n                    break;\n                }\n\n                oldCounter = WndProcCounter;\n            }\n            while (true);\n        }\n\n        private static void HelperThread()\n        {\n            // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n            // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n            using var asyncFlowControl = System.Threading.ExecutionContext.SuppressFlow();\n\n            try\n            {\n                while (true)\n                {\n                    _ = EvSwitch.WaitOne(); // Switching to another machine?\n\n                    if (signalHelperToExit)\n                    {\n                        break;\n                    }\n\n                    if (Common.NewDesMachineID != Common.MachineID && Common.NewDesMachineID != ID.ALL)\n                    {\n                        HideMouseCursor(false);\n                        Common.MainFormDotEx(true);\n                    }\n                    else\n                    {\n                        if (Common.SwitchLocation.Count > 0)\n                        {\n                            Common.SwitchLocation.Count--;\n\n                            // When we want to move mouse by pixels, we add 300k to x and y (search for XY_BY_PIXEL for other related code).\n                            Logger.LogDebug($\"+++++ Moving mouse to {Common.SwitchLocation.X}, {Common.SwitchLocation.Y}\");\n\n                            // MaxXY = 65535 so 100k is safe.\n                            if (Common.SwitchLocation.X > XY_BY_PIXEL - 100000 || Common.SwitchLocation.Y > XY_BY_PIXEL - 100000)\n                            {\n                                InputSimulation.MoveMouse(Common.SwitchLocation.X - XY_BY_PIXEL, Common.SwitchLocation.Y - XY_BY_PIXEL);\n                            }\n                            else\n                            {\n                                InputSimulation.MoveMouseEx(Common.SwitchLocation.X, Common.SwitchLocation.Y);\n                            }\n\n                            Common.MainFormDot();\n                        }\n                    }\n\n                    if (Common.NewDesMachineID == Common.MachineID)\n                    {\n                        ReleaseAllKeys();\n                    }\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n\n            signalHelperToExit = false;\n            Logger.LogDebug(\"^^^Helper Thread exiting...^^^\");\n        }\n\n        internal static void MainFormDotEx(bool bCheckTS)\n        {\n            Logger.LogDebug(\"***** MainFormDotEx:\");\n\n            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n            {\n                int left = Common.PrimaryScreenBounds.Left + ((Common.PrimaryScreenBounds.Right - Common.PrimaryScreenBounds.Left) / 2) - 1;\n                int top = Setting.Values.HideMouse ? 3 : Common.PrimaryScreenBounds.Top + ((Common.PrimaryScreenBounds.Bottom - Common.PrimaryScreenBounds.Top) / 2);\n\n                Common.MainFormVisible = true;\n\n                if (Setting.Values.HideMouse && Setting.Values.StealFocusWhenSwitchingMachine && Common.SendMessageToHelper(0x407, new IntPtr(left), new IntPtr(top), true) == 0)\n                {\n                    try\n                    {\n                        /* When user just switches to the Logon desktop, user is actually on the \"Windows Default Lock Screen\" (LockApp).\n                         * If a click is sent to this during switch, it actually triggers a desktop switch on the local machine causing a reconnection affecting the machine switch.\n                         * We can detect and skip in this case.\n                         * */\n                        IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();\n                        string foreGroundWindowText = GetText(foreGroundWindow);\n\n                        bool mouseClick = true;\n\n                        if (foreGroundWindowText.Equals(\"Windows Default Lock Screen\", StringComparison.OrdinalIgnoreCase))\n                        {\n                            mouseClick = false;\n                        }\n\n                        // Window title may be localized, check process name:\n                        if (mouseClick)\n                        {\n                            _ = NativeMethods.GetWindowThreadProcessId(foreGroundWindow, out uint pid);\n\n                            if (pid > 0)\n                            {\n                                string foreGroundWindowProcess = Process.GetProcessById((int)pid)?.ProcessName;\n\n                                if (foreGroundWindowProcess.Equals(\"LockApp\", StringComparison.OrdinalIgnoreCase))\n                                {\n                                    mouseClick = false;\n                                }\n                            }\n                        }\n\n                        if (mouseClick)\n                        {\n                            InputSimulation.MouseClickDotForm(left + 1, top + 1);\n                        }\n                    }\n                    catch (Exception e)\n                    {\n                        Logger.Log(e);\n                    }\n                }\n            }\n\n            CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);\n        }\n\n        internal static void MainForm3Pixels()\n        {\n            Logger.LogDebug(\"***** MainFormDotLarge:\");\n\n            DoSomethingInUIThread(\n                () =>\n            {\n                MainForm.Left = Common.PrimaryScreenBounds.Left + ((Common.PrimaryScreenBounds.Right - Common.PrimaryScreenBounds.Left) / 2) - 2;\n                MainForm.Top = Setting.Values.HideMouse ? 3 : Common.PrimaryScreenBounds.Top + ((Common.PrimaryScreenBounds.Bottom - Common.PrimaryScreenBounds.Top) / 2) - 1;\n                MainForm.Width = 3;\n                MainForm.Height = 3;\n                MainForm.Opacity = 0.11D;\n                MainForm.TopMost = true;\n\n                if (Setting.Values.HideMouse)\n                {\n                    MainForm.BackColor = Color.Black;\n                    MainForm.Show();\n                    Common.MainFormVisible = true;\n                }\n                else\n                {\n                    MainForm.BackColor = Color.White;\n                    MainForm.Hide();\n                    Common.MainFormVisible = false;\n                }\n            },\n                true);\n\n            CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);\n        }\n\n        internal static void MainFormDot()\n        {\n            DoSomethingInUIThread(\n                () =>\n                {\n                    _ = Common.SendMessageToHelper(0x408, IntPtr.Zero, IntPtr.Zero, false);\n\n                    MainForm.Left = Common.PrimaryScreenBounds.Left + ((Common.PrimaryScreenBounds.Right - Common.PrimaryScreenBounds.Left) / 2) - 1;\n                    MainForm.Top = Setting.Values.HideMouse ? 3 : Common.PrimaryScreenBounds.Top + ((Common.PrimaryScreenBounds.Bottom - Common.PrimaryScreenBounds.Top) / 2);\n                    MainForm.Width = 1;\n                    MainForm.Height = 1;\n                    MainForm.Opacity = 0.15;\n                    MainForm.Hide();\n                    Common.MainFormVisible = false;\n                },\n                true);\n\n            CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);\n        }\n\n        internal static void ToggleIcon()\n        {\n            try\n            {\n                if (toggleIconsIndex < TOGGLE_ICONS_SIZE)\n                {\n                    Common.DoSomethingInUIThread(() => Common.MainForm.ChangeIcon(toggleIcons[toggleIconsIndex++]));\n                }\n                else\n                {\n                    toggleIconsIndex = 0;\n                    toggleIcons = null;\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        internal static void RunDDHelper(bool cleanUp = false)\n        {\n            if (Common.RunOnLogonDesktop || Common.RunOnScrSaverDesktop)\n            {\n                return;\n            }\n\n            if (cleanUp)\n            {\n                try\n                {\n                    Process[] ps = Process.GetProcessesByName(HelperProcessName);\n                    foreach (Process p in ps)\n                    {\n                        p.KillProcess();\n                    }\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                    _ = Common.SendMessageToHelper(SharedConst.QUIT_CMD, IntPtr.Zero, IntPtr.Zero);\n                }\n\n                return;\n            }\n\n            if (!Common.IsMyDesktopActive())\n            {\n                return;\n            }\n\n            if (!Common.IpcChannelCreated)\n            {\n                Logger.TelemetryLogTrace($\"{nameof(Common.IpcChannelCreated)} = {Common.IpcChannelCreated}. {Logger.GetStackTrace(new StackTrace())}\", SeverityLevel.Warning);\n                return;\n            }\n\n            if (!MainForm.IsDisposed)\n            {\n                MainForm.NotifyIcon.Visible = false;\n                MainForm.NotifyIcon.Visible = Setting.Values.ShowOriginalUI;\n            }\n\n            IntPtr h = (IntPtr)NativeMethods.FindWindow(null, Common.HELPER_FORM_TEXT);\n\n            if (h.ToInt32() <= 0)\n            {\n                _ = Common.CreateProcessInInputDesktopSession(\n                    $\"\\\"{Path.GetDirectoryName(Application.ExecutablePath)}\\\\{HelperProcessName}.exe\\\"\",\n                    string.Empty,\n                    Common.GetInputDesktop(),\n                    0);\n\n                HasSwitchedMachineSinceLastCopy = true;\n\n                // Common.CreateLowIntegrityProcess(\"\\\"\" + Path.GetDirectoryName(Application.ExecutablePath) + \"\\\\MouseWithoutBordersHelper.exe\\\"\", string.Empty, 0, false, 0);\n                var processes = Process.GetProcessesByName(HelperProcessName);\n                if (processes?.Length == 0)\n                {\n                    Logger.Log(\"Unable to start helper process.\");\n                    Common.ShowToolTip(\"无法启动无界鼠标帮助模块，剪贴板共享功能失效!\", 5000, ToolTipIcon.Error);\n                }\n                else\n                {\n                    Logger.Log(\"Helper process started.\");\n                }\n            }\n            else\n            {\n                var processes = Process.GetProcessesByName(HelperProcessName);\n                if (processes?.Length > 0)\n                {\n                    Logger.Log(\"Helper process found running.\");\n                }\n                else\n                {\n                    Logger.Log(\"Invalid helper process found running.\");\n                    Common.ShowToolTip(\"找不到无界鼠标帮助模块，剪贴板共享功能失效!\", 5000, ToolTipIcon.Error);\n                }\n            }\n        }\n\n        internal static int SendMessageToHelper(int msg, IntPtr wparam, IntPtr lparam, bool wait = true, bool log = true)\n        {\n            int h = NativeMethods.FindWindow(null, Common.HELPER_FORM_TEXT);\n            int rv = -1;\n\n            if (h > 0)\n            {\n                rv = wait\n                    ? (int)NativeMethods.SendMessage((IntPtr)h, msg, wparam, lparam)\n                    : NativeMethods.PostMessage((IntPtr)h, msg, wparam, lparam) ? 1 : 0;\n            }\n\n            if (log)\n            {\n                Logger.LogDebug($\"SendMessageToHelper: HelperWindow={h}, Return={rv}, msg={msg}, w={wparam.ToInt32()}, l={lparam.ToInt32()}, Post={!wait}\");\n            }\n\n            return rv;\n        }\n\n        internal static bool IsWindows8AndUp()\n        {\n            return (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 2)\n                || Environment.OSVersion.Version.Major > 6;\n        }\n\n        internal static string GetMiniLog(IEnumerable<ControlCollection> optionControls)\n        {\n            string log = string.Empty;\n\n            log += \"=============================================================================================================================\\r\\n\";\n            log += $\"{Application.ProductName} version {Application.ProductVersion}\\r\\n\";\n\n            log += $\"{Setting.Values.Username}/{GetDebugInfo(MyKey)}\\r\\n\";\n            log += $\"{MachineName}/{MachineID}/{DesMachineID}\\r\\n\";\n            log += $\"Id: {Setting.Values.DeviceId}\\r\\n\";\n            log += $\"Matrix: {string.Join(\",\", MachineMatrix)}\\r\\n\";\n            log += $\"McPool: {Setting.Values.MachinePoolString}\\r\\n\";\n\n            log += \"\\r\\nOPTIONS:\\r\\n\";\n\n            foreach (ControlCollection controlCollection in optionControls)\n            {\n                foreach (object c in controlCollection)\n                {\n                    if (c is CheckBox checkBox)\n                    {\n                        log += $\"({(checkBox.Checked ? 1 : 0)}) {checkBox.Text}\\r\\n\";\n                        continue;\n                    }\n\n                    if (c is RadioButton radioButton)\n                    {\n                        log += $\"({(radioButton.Checked ? 1 : 0)}) {radioButton.Name}.[{radioButton.Text}]\\r\\n\";\n                        continue;\n                    }\n\n                    if (c is ComboBox comboBox)\n                    {\n                        log += $\"{comboBox.Name} = {comboBox.Text}\\r\\n\";\n                        continue;\n                    }\n                }\n            }\n\n            log += \"\\r\\n\";\n\n            SocketStuff sk = Sk;\n\n            if (sk?.TcpSockets != null)\n            {\n                foreach (TcpSk tcp in sk.TcpSockets)\n                {\n                    log += $\"{Common.MachineName}{(tcp.IsClient ? \"=>\" : \"<=\")}{tcp.MachineName}({tcp.MachineId}):{tcp.Status}\\r\\n\";\n                }\n            }\n\n            log += string.Format(CultureInfo.CurrentCulture, \"Helper:{0}\\r\\n\", SendMessageToHelper(0x400, IntPtr.Zero, IntPtr.Zero));\n\n            log += Setting.Values.LastPersonalizeLogonScr + \"\\r\\n\";\n            log += \"Name2IP =\\r\\n\" + Setting.Values.Name2IP + \"\\r\\n\";\n\n            log += \"Last 10 trace messages:\\r\\n\";\n\n            log += string.Join(Environment.NewLine, Logger.LogCounter.Select(item => $\"({item.Value}): {item.Key}\").Take(10));\n\n            log += \"\\r\\n=============================================================================================================================\";\n\n            return log;\n        }\n\n        internal static bool GetUserName()\n        {\n            if (string.IsNullOrEmpty(Setting.Values.Username) && !Common.RunOnLogonDesktop)\n            {\n                if (Program.User.Contains(\"system\", StringComparison.CurrentCultureIgnoreCase))\n                {\n                    _ = Common.ImpersonateLoggedOnUserAndDoSomething(() =>\n                    {\n                        Setting.Values.Username = WindowsIdentity.GetCurrent(true).Name;\n                    });\n                }\n                else\n                {\n                    Setting.Values.Username = Program.User;\n                }\n\n                Logger.LogDebug(\"[Username] = \" + Setting.Values.Username);\n            }\n\n            return !string.IsNullOrEmpty(Setting.Values.Username);\n        }\n\n        internal static void ShowOneWayModeMessage()\n        {\n            ToggleShowTopMostMessage(\n    @\"\nDue to Security Controls, a remote device cannot control a SAW device.\nPlease use the keyboard and Mouse from the SAW device.\n(Press Esc to hide this message)\n\",\n    string.Empty,\n    10);\n        }\n\n        internal static void ApplyCADSetting()\n        {\n            try\n            {\n                if (Setting.Values.DisableCAD)\n                {\n                    RegistryKey k = Registry.LocalMachine.CreateSubKey(@\"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\");\n                    if (k != null)\n                    {\n                        k.SetValue(\"DisableCAD\", 1, RegistryValueKind.DWord);\n                        k.Close();\n                    }\n                }\n                else\n                {\n                    RegistryKey k = Registry.LocalMachine.CreateSubKey(@\"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System\");\n                    if (k != null)\n                    {\n                        k.SetValue(\"DisableCAD\", 0, RegistryValueKind.DWord);\n                        k.Close();\n                    }\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.MachineStuff.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Drawing;\nusing System.Globalization;\nusing System.Linq;\nusing System.Threading;\nusing System.Windows.Forms;\n\nusing Microsoft.PowerToys.Telemetry;\n\n// <summary>\n//     Machine setup/switching implementation.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\n\nnamespace MouseWithoutBorders\n{\n    internal struct MachineInf\n    {\n        internal string Name;\n        internal ID Id;\n        internal long Time;\n    }\n\n    internal class MyRectangle\n    {\n        internal int Left;\n        internal int Top;\n        internal int Right;\n        internal int Bottom;\n    }\n\n    internal partial class Common\n    {\n        private static readonly Lock McMatrixLock = new();\n\n        internal const byte MAX_MACHINE = 4;\n        internal const byte MAX_SOCKET = MAX_MACHINE * 2;\n        internal const long HEARTBEAT_TIMEOUT = 1500000; // 30 Mins\n        private const int SKIP_PIXELS = 1;\n        private const int JUMP_PIXELS = 2;\n\n#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter\n        internal static ID desMachineID;\n#pragma warning restore SA1307\n        internal static string DesMachineName = string.Empty;\n        private static ID newDesMachineID;\n#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter\n        internal static ID newDesMachineIdEx;\n#pragma warning restore SA1307\n        private static ID dropMachineID;\n\n        private static long lastJump = Common.GetTick();\n        private static MyRectangle desktopBounds = new();\n        private static MyRectangle primaryScreenBounds = new();\n        private static MachinePool _machinePool;\n\n        internal static MachinePool MachinePool\n        {\n            get\n            {\n                _machinePool ??= new MachinePool();\n                return _machinePool;\n            }\n        }\n\n        internal static MyRectangle PrimaryScreenBounds => Common.primaryScreenBounds;\n\n        internal static MouseLocation SwitchLocation = new();\n\n        internal static ID NewDesMachineID\n        {\n            get => Common.newDesMachineID;\n            set => Common.newDesMachineID = value;\n        }\n\n        internal static MyRectangle DesktopBounds => Common.desktopBounds;\n\n#if OLD_VERSION\n        static bool MoveToMyNeighbourIfNeeded(int x, int y)\n        {\n            if (Math.Abs(x) > 10) LastX = x;\n            if (Math.Abs(y) > 10) LastY = y;\n            if (GetTick() - lastJump < 500 || desMachineID == IP.ALL) return false;\n            if (desMachineID == machineID)\n            {\n                if (x < desktopBounds.Left + skipPixels) return MoveLeft(x, y, x - desktopBounds.Left, 0);\n            }\n            else\n            {\n                if (x < primaryScreenBounds.Left + skipPixels)\n                {\n                    if (MoveLeft(x, y, x - primaryScreenBounds.Left, 0))\n                    {\n                        return true;\n                    }\n                    else\n                    {\n                        if (desktopBounds.Left < primaryScreenBounds.Left)\n                        {\n                            RequestedX_Ex = primaryScreenBounds.Left;\n                            RequestedY_Ex = y;\n                            return true;\n                        }\n                    }\n                }\n            }\n\n            if (desMachineID == machineID)\n            {\n                if (x > desktopBounds.Right - skipPixels) return MoveRight(x, y, x - desktopBounds.Right, 0);\n            }\n            else\n            {\n                if (x > primaryScreenBounds.Right - skipPixels)\n                {\n                    if (MoveRight(x, y, x - primaryScreenBounds.Right, 0))\n                    {\n                        return true;\n                    }\n                    else\n                    {\n                        if (desktopBounds.Right > primaryScreenBounds.Right)\n                        {\n                            RequestedX_Ex = primaryScreenBounds.Right;\n                            RequestedY_Ex = y;\n                            return true;\n                        }\n                    }\n                }\n            }\n\n            if (desMachineID == machineID)\n            {\n                if (y < desktopBounds.Top + skipPixels) return MoveUp(x, y, 0, y - desktopBounds.Top);\n            }\n            else\n            {\n                if (y < primaryScreenBounds.Top + skipPixels)\n                {\n                    if (MoveUp(x, y, 0, y - primaryScreenBounds.Top))\n                    {\n                        return true;\n                    }\n                    else\n                    {\n                        if (desktopBounds.Top < primaryScreenBounds.Top)\n                        {\n                            RequestedX_Ex = x;\n                            RequestedY_Ex = primaryScreenBounds.Top;\n                            return true;\n                        }\n                    }\n                }\n            }\n\n            if (desMachineID == machineID)\n            {\n                if (y > desktopBounds.Bottom - skipPixels) return MoveDown(x, y, 0, y - desktopBounds.Bottom);\n            }\n            else\n            {\n                if (y > primaryScreenBounds.Bottom - skipPixels)\n                {\n                    if (MoveDown(x, y, 0, y - primaryScreenBounds.Bottom))\n                    {\n                        return true;\n                    }\n                    else\n                    {\n                        if (desktopBounds.Bottom > primaryScreenBounds.Bottom)\n                        {\n                            RequestedX_Ex = x;\n                            RequestedY_Ex = primaryScreenBounds.Bottom;\n                            return true;\n                        }\n                    }\n                }\n            }\n\n            return false;\n        }\n#else\n\n        private static Point ConvertToUniversalValue(Point p, MyRectangle r)\n        {\n            if (!p.IsEmpty)\n            {\n                p.X = (p.X - r.Left) * 65535 / (r.Right - r.Left);\n                p.Y = (p.Y - r.Top) * 65535 / (r.Bottom - r.Top);\n            }\n\n            return p;\n        }\n\n        /* Let's say we have 3 machines A, B, and C. A is the controller machine.\n         * (x, y) is the current Mouse position in pixel.\n         * If Setting.Values.MoveMouseRelatively then (x, y) can be from any machine having the value bounded by desktopBounds (can be negative)\n         * Else (x, y) is from the controller machine which is bounded by ONLY primaryScreenBounds (>=0);\n         *\n         * The return point is from 0 to 65535 which is then mapped to the desktop of the new controlled machine by the SendInput method.\n         *  Let's say user is switching from machine B to machine C:\n         *      If Setting.Values.MoveMouseRelatively the this method is called by B and the return point is calculated by B and sent back to A, A will use it to move Mouse to the right position when switching to C.\n         *      Else this method is called by A and the return point is calculated by A.\n         * */\n\n        internal static Point MoveToMyNeighbourIfNeeded(int x, int y, ID desMachineID)\n        {\n            newDesMachineIdEx = desMachineID;\n\n            if (Math.Abs(x) > 10)\n            {\n                LastX = x;\n            }\n\n            if (Math.Abs(y) > 10)\n            {\n                LastY = y;\n            }\n\n            if ((GetTick() - lastJump < 100) || desMachineID == ID.ALL)\n            {\n                return Point.Empty;\n            }\n\n            if (Setting.Values.BlockMouseAtCorners)\n            {\n                lock (SensitivePoints)\n                {\n                    foreach (Point p in SensitivePoints)\n                    {\n                        if (Math.Abs(p.X - x) < 100 && Math.Abs(p.Y - y) < 100)\n                        {\n                            return Point.Empty;\n                        }\n                    }\n                }\n            }\n\n            /* If Mouse is moving in the controller machine and this method is called by the controller machine.\n             * Or if Mouse is moving in the controlled machine and this method is called by the controlled machine and Setting.Values.MoveMouseRelative.\n             * */\n            if (desMachineID == MachineID)\n            {\n                if (x < desktopBounds.Left + SKIP_PIXELS)\n                {\n                    return MoveLeft(x, y);\n                }\n                else if (x >= desktopBounds.Right - SKIP_PIXELS)\n                {\n                    return MoveRight(x, y);\n                }\n                else if (y < desktopBounds.Top + SKIP_PIXELS)\n                {\n                    return MoveUp(x, y);\n                }\n                else if (y >= desktopBounds.Bottom - SKIP_PIXELS)\n                {\n                    return MoveDown(x, y);\n                }\n            }\n\n            /* If Mouse is moving in the controlled machine and this method is called by the controller machine and !Setting.Values.MoveMouseRelative.\n             * Mouse location is scaled from the primary screen bound of the controller machine regardless of how many monitors the controlled machine may have.\n             * */\n            else\n            {\n                if (x < primaryScreenBounds.Left + SKIP_PIXELS)\n                {\n                    return MoveLeft(x, y);\n                }\n                else if (x >= primaryScreenBounds.Right - SKIP_PIXELS)\n                {\n                    return MoveRight(x, y);\n                }\n                else if (y < primaryScreenBounds.Top + SKIP_PIXELS)\n                {\n                    return MoveUp(x, y);\n                }\n                else if (y >= primaryScreenBounds.Bottom - SKIP_PIXELS)\n                {\n                    return MoveDown(x, y);\n                }\n            }\n\n            return Point.Empty;\n        }\n\n#endif\n\n        [SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification = \"Dotnet port with style preservation\")]\n        private static Point MoveRight(int x, int y)\n        {\n            string[] mc = LiveMachineMatrix;\n            if (mc == null)\n            {\n                return Point.Empty;\n            }\n\n            bool oneRow = Setting.Values.MatrixOneRow;\n\n            string currentMachine = NameFromID(desMachineID);\n            if (currentMachine == null)\n            {\n                return Point.Empty;\n            }\n\n            ID newID;\n            if (oneRow)\n            {\n                bool found = false;\n                for (int i = 0; i < MAX_MACHINE; i++)\n                {\n                    if (currentMachine.Trim().Equals(mc[i], StringComparison.OrdinalIgnoreCase))\n                    {\n                        for (int j = i; j < MAX_MACHINE - 1; j++)\n                        {\n                            if (mc[j + 1] != null && mc[j + 1].Length > 0)\n                            {\n                                if ((newID = IdFromName(mc[j + 1])) > 0)\n                                {\n                                    newDesMachineIdEx = newID;\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n\n                        if (!found && Setting.Values.MatrixCircle)\n                        {\n                            for (int j = 0; j < i; j++)\n                            {\n                                if (mc[j] != null && mc[j].Length > 0)\n                                {\n                                    if ((newID = IdFromName(mc[j])) > 0)\n                                    {\n                                        newDesMachineIdEx = newID;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n\n                        break;\n                    }\n                }\n            }\n            else\n            {\n                if (currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)\n                    && (mc[1].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[1])) > 0)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n                else if (currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)\n                    && (mc[3].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[3])) > 0)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n                else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)\n                    && (mc[0].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[0])) > 0)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n                else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)\n                    && (mc[2].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[2])) > 0)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n            }\n\n            // THIS LOGIC IS THE SAME FOR Move*(int x, int y) METHODS.\n            if (newDesMachineIdEx != desMachineID)\n            {\n                Logger.LogDebug(\"Move Right\");\n\n                if (!Setting.Values.MoveMouseRelatively)\n                {\n                    if (newDesMachineIdEx == MachineID)\n                    {\n                        /* Switching back to the controller machine, we need to scale up to the desktopBounds from primaryScreenBounds (sine !Setting.Values.MoveMouseRelatively).\n                         * primaryScreenBounds => 65535 => desktopBounds, so that the Mouse position is mapped to the right position when the controller machine has multiple monitors.\n                         * */\n                        return ConvertToUniversalValue(new Point(primaryScreenBounds.Left + JUMP_PIXELS, y), primaryScreenBounds);\n                    }\n                    else\n                    {\n                        if (desMachineID == MachineID)\n                        {\n                            /* Switching FROM the controller machine, since Mouse was not bounded/locked to the primary screen,\n                             * Mouse position can just be mapped from desktopBounds to desktopBounds\n                             * desktopBounds => 65535 => desktopBounds.\n                             * */\n                            return ConvertToUniversalValue(new Point(desktopBounds.Left + JUMP_PIXELS, y), desktopBounds);\n                        }\n                        else\n                        {\n                            /* Switching between two machines where non of them is the controller machine.\n                             * Since the current Mouse position is \"mapped\" from the primary monitor of the controller machine,\n                             * new Mouse position for the new controlled machine needs to be calculated from this as well.\n                             * primaryScreenBounds => 65535 => desktopBounds\n                             * */\n                            return ConvertToUniversalValue(new Point(primaryScreenBounds.Left + JUMP_PIXELS, y), primaryScreenBounds);\n                        }\n                    }\n                }\n                else\n                {\n                    /* In the case where Mouse is moved relatively, Mouse position is simply mapped from desktopBounds to desktopBounds.\n                     * desktopBounds => 65535 => desktopBounds.\n                     * */\n                    return ConvertToUniversalValue(new Point(desktopBounds.Left + JUMP_PIXELS, y), desktopBounds);\n                }\n            }\n\n            return Point.Empty;\n        }\n\n        [SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Justification = \"Dotnet port with style preservation\")]\n        private static Point MoveLeft(int x, int y)\n        {\n            string[] mc = LiveMachineMatrix;\n            if (mc == null)\n            {\n                return Point.Empty;\n            }\n\n            bool oneRow = Setting.Values.MatrixOneRow;\n\n            string currentMachine = NameFromID(desMachineID);\n            if (currentMachine == null)\n            {\n                return Point.Empty;\n            }\n\n            ID newID;\n            if (oneRow)\n            {\n                bool found = false;\n                for (int i = MAX_MACHINE - 1; i >= 0; i--)\n                {\n                    if (currentMachine.Trim().Equals(mc[i], StringComparison.OrdinalIgnoreCase))\n                    {\n                        for (int j = i; j > 0; j--)\n                        {\n                            if (mc[j - 1] != null && mc[j - 1].Length > 0)\n                            {\n                                if ((newID = IdFromName(mc[j - 1])) != ID.NONE)\n                                {\n                                    newDesMachineIdEx = newID;\n                                    found = true;\n                                    break;\n                                }\n                            }\n                        }\n\n                        if (!found && Setting.Values.MatrixCircle)\n                        {\n                            for (int j = MAX_MACHINE - 1; j > i; j--)\n                            {\n                                if (mc[j] != null && mc[j].Length > 0)\n                                {\n                                    if ((newID = IdFromName(mc[j])) != ID.NONE)\n                                    {\n                                        newDesMachineIdEx = newID;\n                                        break;\n                                    }\n                                }\n                            }\n                        }\n\n                        break;\n                    }\n                }\n            }\n            else\n            {\n                if (currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)\n                    && (mc[0].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[0])) != ID.NONE)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n                else if (currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)\n                    && (mc[2].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[2])) != ID.NONE)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n                else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)\n                    && (mc[1].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[1])) != ID.NONE)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n                else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)\n                    && (mc[3].Length > 0))\n                {\n                    if ((newID = IdFromName(mc[3])) != ID.NONE)\n                    {\n                        newDesMachineIdEx = newID;\n                    }\n                }\n            }\n\n            if (newDesMachineIdEx != desMachineID)\n            {\n                Logger.LogDebug(\"Move Left\");\n\n                return !Setting.Values.MoveMouseRelatively\n                    ? newDesMachineIdEx == MachineID\n                        ? ConvertToUniversalValue(new Point(primaryScreenBounds.Right - JUMP_PIXELS, y), primaryScreenBounds)\n                        : desMachineID == MachineID\n                            ? ConvertToUniversalValue(new Point(desktopBounds.Right - JUMP_PIXELS, y), desktopBounds)\n                            : ConvertToUniversalValue(new Point(primaryScreenBounds.Right - JUMP_PIXELS, y), primaryScreenBounds)\n                    : ConvertToUniversalValue(new Point(desktopBounds.Right - JUMP_PIXELS, y), desktopBounds);\n            }\n\n            return Point.Empty;\n        }\n\n        private static Point MoveUp(int x, int y)\n        {\n            if (Setting.Values.MatrixOneRow)\n            {\n                return Point.Empty;\n            }\n\n            string[] mc = LiveMachineMatrix;\n            if (mc == null)\n            {\n                return Point.Empty;\n            }\n\n            string currentMachine = NameFromID(desMachineID);\n            if (currentMachine == null)\n            {\n                return Point.Empty;\n            }\n\n            ID newID;\n            if (currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)\n                && (mc[0].Length > 0))\n            {\n                if ((newID = IdFromName(mc[0])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n            else if (currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)\n                && (mc[1].Length > 0))\n            {\n                if ((newID = IdFromName(mc[1])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n            else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)\n                && (mc[2].Length > 0))\n            {\n                if ((newID = IdFromName(mc[2])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n            else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)\n                && (mc[3].Length > 0))\n            {\n                if ((newID = IdFromName(mc[3])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n\n            if (newDesMachineIdEx != desMachineID)\n            {\n                Logger.LogDebug(\"Move Up\");\n\n                return !Setting.Values.MoveMouseRelatively\n                    ? newDesMachineIdEx == MachineID\n                        ? ConvertToUniversalValue(new Point(x, primaryScreenBounds.Bottom - JUMP_PIXELS), primaryScreenBounds)\n                        : desMachineID == MachineID\n                            ? ConvertToUniversalValue(new Point(x, desktopBounds.Bottom - JUMP_PIXELS), desktopBounds)\n                            : ConvertToUniversalValue(new Point(x, primaryScreenBounds.Bottom - JUMP_PIXELS), primaryScreenBounds)\n                    : ConvertToUniversalValue(new Point(x, desktopBounds.Bottom - JUMP_PIXELS), desktopBounds);\n            }\n\n            return Point.Empty;\n        }\n\n        private static Point MoveDown(int x, int y)\n        {\n            if (Setting.Values.MatrixOneRow)\n            {\n                return Point.Empty;\n            }\n\n            string[] mc = LiveMachineMatrix;\n            if (mc == null)\n            {\n                return Point.Empty;\n            }\n\n            string currentMachine = NameFromID(desMachineID);\n            if (currentMachine == null)\n            {\n                return Point.Empty;\n            }\n\n            ID newID;\n            if (currentMachine.Trim().Equals(mc[0], StringComparison.OrdinalIgnoreCase) && (mc[2] != null)\n                && (mc[2].Length > 0))\n            {\n                if ((newID = IdFromName(mc[2])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n            else if (currentMachine.Trim().Equals(mc[1], StringComparison.OrdinalIgnoreCase) && (mc[3] != null)\n                && (mc[3].Length > 0))\n            {\n                if ((newID = IdFromName(mc[3])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n\n            if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[2], StringComparison.OrdinalIgnoreCase) && (mc[0] != null)\n                && (mc[0].Length > 0))\n            {\n                if ((newID = IdFromName(mc[0])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n            else if (Setting.Values.MatrixCircle && currentMachine.Trim().Equals(mc[3], StringComparison.OrdinalIgnoreCase) && (mc[1] != null)\n                && (mc[1].Length > 0))\n            {\n                if ((newID = IdFromName(mc[1])) != ID.NONE)\n                {\n                    newDesMachineIdEx = newID;\n                }\n            }\n\n            if (newDesMachineIdEx != desMachineID)\n            {\n                Logger.LogDebug(\"Move Down\");\n\n                return !Setting.Values.MoveMouseRelatively\n                    ? newDesMachineIdEx == MachineID\n                        ? ConvertToUniversalValue(new Point(x, primaryScreenBounds.Top + JUMP_PIXELS), primaryScreenBounds)\n                        : desMachineID == MachineID\n                            ? ConvertToUniversalValue(new Point(x, desktopBounds.Top + JUMP_PIXELS), desktopBounds)\n                            : ConvertToUniversalValue(new Point(x, primaryScreenBounds.Top + JUMP_PIXELS), primaryScreenBounds)\n                    : ConvertToUniversalValue(new Point(x, desktopBounds.Top + JUMP_PIXELS), desktopBounds);\n            }\n\n            return Point.Empty;\n        }\n\n        internal static bool RemoveDeadMachines(ID ip)\n        {\n            bool rv = false;\n\n            // Here we are removing a dead machine by IP.\n            foreach (MachineInf inf in Common.MachinePool.ListAllMachines())\n            {\n                if (inf.Id == ip)\n                {\n                    if (MachinePool.SetMachineDisconnected(inf.Name))\n                    {\n                        rv = true;\n                    }\n\n                    Logger.LogDebug(\"<><><><><>>><><><<><><><><><><><><><><>><><><><><><><><><><><\" + inf.Name);\n                }\n            }\n\n            return rv;\n        }\n\n        internal static void RemoveDeadMachines()\n        {\n            // list of live/dead machines is now automatically up-to-date\n            // if it changed we need to update the UI.\n            // for now assume it changed.\n            // Common.MachinePool.ResetIPAddressesForDeadMachines();\n            // DoSomethingInUIThread(UpdateMenu);\n            Common.UpdateMachinePoolStringSetting();\n\n            // Make sure MachinePool still holds this machine.\n            if (Common.MachinePool.LearnMachine(MachineName))\n            {\n                _ = Common.MachinePool.TryUpdateMachineID(MachineName, MachineID, false);\n            }\n        }\n\n        internal static string AddToMachinePool(DATA package)\n        {\n            // Log(\"********** AddToMachinePool called: \" + package.src.ToString(CultureInfo.InvariantCulture));\n\n            // There should be no duplicates in machine pool.\n            string name = package.MachineName;\n\n            // a few things happening here:\n            // 1) find a matching machine (by name)\n            // 2) update its ID and time\n            // 3) logging\n            // 4) updating some variables - desMachineID/newDesMachineID\n            // 5) return the matched name (trimmed) - only in the event of a match\n            if (Common.MachinePool.TryFindMachineByName(name, out MachineInf machineInfo))\n            {\n                _ = Common.MachinePool.TryUpdateMachineID(machineInfo.Name, machineInfo.Id, true);\n\n                _ = Common.MachinePool.TryUpdateMachineID(machineInfo.Name, package.Src, true);\n\n                if (machineInfo.Name.Equals(DesMachineName, StringComparison.OrdinalIgnoreCase))\n                {\n                    Logger.LogDebug(\"AddToMachinePool: Des ID updated: \" + DesMachineID.ToString() + \"/\" + package.Src.ToString());\n                    newDesMachineID = desMachineID = package.Src;\n                }\n\n                return machineInfo.Name;\n            }\n            else\n            {\n                if (Common.MachinePool.LearnMachine(name))\n                {\n                    _ = Common.MachinePool.TryUpdateMachineID(name, package.Src, true);\n                }\n                else\n                {\n                    Logger.LogDebug(\"AddToMachinePool: could not add a new machine: \" + name);\n                    return \"The 5th machine\";\n                }\n            }\n\n            // if (machineCount != saved)\n            {\n                // DoSomethingInUIThread(UpdateMenu);\n                Common.UpdateMachinePoolStringSetting();\n            }\n\n            // NOTE(yuyoyuppe): automatically active \"bidirectional\" control between the machines.\n            string[] st = new string[Common.MAX_MACHINE];\n            Array.Fill(st, string.Empty);\n            var machines = Common.MachinePool.ListAllMachines();\n            for (int i = 0; i < machines.Count; ++i)\n            {\n                if (machines[i].Id != ID.NONE && machines[i].Id != ID.ALL)\n                {\n                    st[i] = machines[i].Name;\n                }\n            }\n\n            Common.MachineMatrix = st;\n            Common.ReopenSockets(true);\n            Common.SendMachineMatrix();\n\n            Logger.LogDebug(\"Machine added: \" + name + \"/\" + package.Src.ToString());\n            UpdateClientSockets(\"AddToMachinePool\");\n            return name;\n        }\n\n        internal static void UpdateClientSockets(string logHeader)\n        {\n            Logger.LogDebug(\"UpdateClientSockets: \" + logHeader);\n            Sk?.UpdateTCPClients();\n        }\n\n        private static SettingsForm settings;\n\n        internal static SettingsForm Settings\n        {\n            get => Common.settings;\n            set => Common.settings = value;\n        }\n\n        internal static void ShowSetupForm(bool reopenSockets = false)\n        {\n            Logger.LogDebug(\"========== BEGIN THE SETUP EXPERIENCE ==========\", true);\n            Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();\n            Common.GeneratedKey = true;\n\n            if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())\n            {\n                Logger.Log(\"Not physical console session.\");\n                _ = MessageBox.Show(\n                    \"请在物理终端会话中运行.\\r\\n本软件不支持在远程连接和虚拟机中使用.\",\n                    Application.ProductName,\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Stop);\n                return;\n            }\n\n            if (settings == null)\n            {\n                settings = new SettingsForm();\n                settings.Show();\n            }\n            else\n            {\n                settings.Close();\n                Common.MMSleep(0.3);\n                settings = new SettingsForm();\n                settings.Show();\n            }\n\n            if (reopenSockets)\n            {\n                Common.ReopenSockets(true);\n            }\n        }\n\n        internal static void CloseSetupForm()\n        {\n            if (settings != null)\n            {\n                settings.Close();\n                settings = null;\n            }\n        }\n\n        internal static void ShowMachineMatrix()\n        {\n            if (!Setting.Values.ShowOriginalUI)\n            {\n                return;\n            }\n\n            if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())\n            {\n                Common.ShowToolTip(\"本软件不支持在远程连接和虚拟机中使用.\", 5000);\n            }\n\n#if NEW_SETTINGS_FORM\n            Common.ShowSetupForm();\n#else\n            if (Setting.Values.FirstRun && !Common.AtLeastOneSocketConnected())\n            {\n                Common.ShowSetupForm();\n            }\n            else\n            {\n                PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIOpenedEvent());\n\n                if (MatrixForm == null)\n                {\n                    MatrixForm = new FrmMatrix();\n                    MatrixForm.Show();\n\n                    if (MainForm != null)\n                    {\n                        MainForm.NotifyIcon.Visible = false;\n                        MainForm.NotifyIcon.Visible = Setting.Values.ShowOriginalUI;\n                    }\n                }\n                else\n                {\n                    MatrixForm.WindowState = FormWindowState.Normal;\n                    MatrixForm.Activate();\n                }\n            }\n#endif\n        }\n\n        private static string[] mcMatrix;\n\n        internal static string[] MachineMatrix\n        {\n            get\n            {\n                lock (McMatrixLock)\n                {\n                    if (mcMatrix == null)\n                    {\n                        string s = Setting.Values.MachineMatrixString;\n\n                        if (!string.IsNullOrEmpty(s))\n                        {\n                            mcMatrix = s.Split(new char[] { ',' });\n\n                            if (mcMatrix == null || mcMatrix.Length != MAX_MACHINE)\n                            {\n                                mcMatrix = new string[MAX_MACHINE] { string.Empty, string.Empty, string.Empty, string.Empty };\n                            }\n                        }\n                        else\n                        {\n                            mcMatrix = new string[MAX_MACHINE] { string.Empty, string.Empty, string.Empty, string.Empty };\n                        }\n                    }\n\n                    return mcMatrix;\n                }\n            }\n\n            set\n            {\n                lock (McMatrixLock)\n                {\n                    if (value == null)\n                    {\n                        mcMatrix = null; // Force read from registry next time.\n                        return;\n                    }\n                    else\n                    {\n                        Setting.Values.MachineMatrixString = string.Join(\",\", mcMatrix = value);\n                    }\n                }\n\n                DoSomethingInUIThread(() =>\n                {\n                    MainForm.ChangeIcon(-1);\n                    MainForm.UpdateNotifyIcon();\n                });\n            }\n        }\n\n        private static string[] LiveMachineMatrix\n        {\n            get\n            {\n                bool twoRow = !Setting.Values.MatrixOneRow;\n                string[] connectedMachines = twoRow ? MachineMatrix : MachineMatrix.Select(m => IsConnectedTo(IdFromName(m)) ? m : string.Empty).ToArray();\n                Logger.LogDebug($\"Matrix: {string.Join(\",\", MachineMatrix)}, Connected: {string.Join(\",\", connectedMachines)}\");\n\n                return connectedMachines;\n            }\n        }\n\n        internal static void UpdateMachinePoolStringSetting()\n        {\n            Setting.Values.MachinePoolString = Common.MachinePool.SerializedAsString();\n        }\n\n        internal static void SendMachineMatrix()\n        {\n            if (MachineMatrix == null)\n            {\n                return;\n            }\n\n            DATA package = new();\n\n            for (int i = 0; i < MachineMatrix.Length; i++)\n            {\n                package.MachineName = MachineMatrix[i];\n\n                package.Type = PackageType.Matrix\n                    | (Setting.Values.MatrixCircle ? PackageType.MatrixSwapFlag : 0)\n                    | (Setting.Values.MatrixOneRow ? 0 : PackageType.MatrixTwoRowFlag);\n\n                package.Src = (ID)(i + 1);\n                package.Des = ID.ALL;\n\n                SkSend(package, null, false);\n\n                Logger.LogDebug($\"matrixIncludedMachine sent: [{i + 1}]:[{MachineMatrix[i]}]\");\n            }\n        }\n\n        internal static void UpdateMachineMatrix(DATA package)\n        {\n            uint i = (uint)package.Src;\n            string matrixIncludedMachine = package.MachineName;\n\n            if (i is > 0 and <= MAX_MACHINE)\n            {\n                Logger.LogDebug($\"matrixIncludedMachine: [{i}]:[{matrixIncludedMachine}]\");\n\n                MachineMatrix[i - 1] = matrixIncludedMachine;\n\n                if (i == MAX_MACHINE)\n                {\n                    Setting.Values.MatrixCircle = (package.Type & PackageType.MatrixSwapFlag) == PackageType.MatrixSwapFlag;\n                    Setting.Values.MatrixOneRow = !((package.Type & PackageType.MatrixTwoRowFlag) == PackageType.MatrixTwoRowFlag);\n                    MachineMatrix = MachineMatrix; // Save\n\n                    Common.ReopenSocketDueToReadError = true;\n\n                    UpdateClientSockets(\"UpdateMachineMatrix\");\n\n                    Setting.Values.Changed = true;\n                }\n            }\n            else\n            {\n                Logger.LogDebug(\"Invalid machine Matrix package!\");\n            }\n        }\n\n        internal static void SwitchToMachine(string name)\n        {\n            ID id = Common.MachinePool.ResolveID(name);\n\n            if (id != ID.NONE)\n            {\n                // Ask current machine to hide the Mouse cursor\n                if (desMachineID != MachineID)\n                {\n                    SendPackage(desMachineID, PackageType.HideMouse);\n                }\n\n                NewDesMachineID = DesMachineID = id;\n                SwitchLocation.X = XY_BY_PIXEL + primaryScreenBounds.Left + ((primaryScreenBounds.Right - primaryScreenBounds.Left) / 2);\n                SwitchLocation.Y = XY_BY_PIXEL + primaryScreenBounds.Top + ((primaryScreenBounds.Bottom - primaryScreenBounds.Top) / 2);\n                SwitchLocation.ResetCount();\n                Common.UpdateMultipleModeIconAndMenu();\n                HideMouseCursor(false);\n                _ = EvSwitch.Set();\n            }\n        }\n\n        internal static void SwitchToMultipleMode(bool multipleMode, bool centerScreen)\n        {\n            if (multipleMode)\n            {\n                PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersMultipleModeEvent());\n                NewDesMachineID = DesMachineID = ID.ALL;\n            }\n            else\n            {\n                NewDesMachineID = DesMachineID = MachineID;\n            }\n\n            if (centerScreen)\n            {\n                MoveMouseToCenter();\n            }\n\n            ReleaseAllKeys();\n\n            Common.UpdateMultipleModeIconAndMenu();\n        }\n\n        internal static bool CheckSecondInstance(bool sendMessage = false)\n        {\n            int h;\n\n            if ((h = NativeMethods.FindWindow(null, Setting.Values.MyID)) > 0)\n            {\n                return true;\n            }\n\n            return false;\n        }\n\n        private static EventWaitHandle oneInstanceCheck;\n\n        internal static void AssertOneInstancePerDesktopSession()\n        {\n            string eventName = $\"Global\\\\{Application.ProductName}-{FrmAbout.AssemblyVersion}-{GetMyDesktop()}-{CurrentProcess.SessionId}\";\n            oneInstanceCheck = new EventWaitHandle(false, EventResetMode.ManualReset, eventName, out bool created);\n\n            if (!created)\n            {\n                Logger.TelemetryLogTrace($\"Second instance found: {eventName}.\", SeverityLevel.Warning, true);\n                CurrentProcess.KillProcess(true);\n            }\n        }\n\n        internal static ID IdFromName(string name)\n        {\n            return Common.MachinePool.ResolveID(name);\n        }\n\n        internal static string NameFromID(ID id)\n        {\n            foreach (MachineInf inf in Common.MachinePool.TryFindMachineByID(id))\n            {\n                if (!string.IsNullOrEmpty(inf.Name))\n                {\n                    return inf.Name;\n                }\n            }\n\n            return null;\n        }\n\n        internal static bool InMachineMatrix(string name)\n        {\n            if (MachineMatrix == null || string.IsNullOrWhiteSpace(name))\n            {\n                return false;\n            }\n\n            foreach (string st in MachineMatrix)\n            {\n                if (!string.IsNullOrWhiteSpace(st) && st.Trim().Equals(name.Trim(), StringComparison.OrdinalIgnoreCase))\n                {\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        internal static void ClearComputerMatrix()\n        {\n            Common.MachineMatrix = new string[Common.MAX_MACHINE] { Common.MachineName.Trim(), string.Empty, string.Empty, string.Empty };\n            Common.MachinePool.Initialize(new string[] { Common.MachineName });\n            Common.UpdateMachinePoolStringSetting();\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Common.Service.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Linq;\nusing System.ServiceProcess;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\n// <summary>\n//     Service control code.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\n\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1300:SpecifyMessageBoxOptions\", Scope = \"member\", Target = \"MouseWithoutBorders.Common.#StartMouseWithoutBordersService()\", Justification = \"Dotnet port with style preservation\")]\n\nnamespace MouseWithoutBorders\n{\n    internal partial class Common\n    {\n        private static bool shownErrMessage;\n        private static DateTime lastStartServiceTime = DateTime.UtcNow;\n\n        internal static void StartMouseWithoutBordersService(string desktopToRunMouseWithoutBordersOn = null, string startTag1 = \"byapp\", string startTag2 = null)\n        {\n            // NOTE(@yuyoyuppe): the new flow assumes we run both mwb processes directly from the svc.\n            if (Common.RunWithNoAdminRight || true)\n            {\n                return;\n            }\n\n            Logger.Log($\"{nameof(StartMouseWithoutBordersService)}: {Logger.GetStackTrace(new StackTrace())}.\");\n\n            Task task = Task.Run(() =>\n            {\n                Process[] ps = Process.GetProcessesByName(\"MouseWithoutBordersSvc\");\n\n                if (ps.Length != 0)\n                {\n                    if (DateTime.UtcNow - lastStartServiceTime < TimeSpan.FromSeconds(5))\n                    {\n                        Logger.Log($\"{nameof(StartMouseWithoutBordersService)}: Aborted.\");\n                        return;\n                    }\n\n                    foreach (Process pp in ps)\n                    {\n                        Logger.Log(string.Format(CultureInfo.InvariantCulture, \"Killing process MouseWithoutBordersSvc {0}.\", pp.Id));\n                        pp.KillProcess();\n                    }\n                }\n\n                lastStartServiceTime = DateTime.UtcNow;\n                ServiceController service = new(\"MouseWithoutBordersSvc\");\n\n                try\n                {\n                    Logger.Log(\"Starting \" + service.ServiceName);\n                }\n                catch (Exception)\n                {\n                    if (!shownErrMessage)\n                    {\n                        shownErrMessage = true;\n                        _ = MessageBox.Show(\n                            Application.ProductName + \" 尚未安装，请先运行 Setup.exe!\",\n                            Application.ProductName,\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                    }\n\n                    return;\n                }\n\n                try\n                {\n                    int c = 0;\n\n                    while (service.Status != ServiceControllerStatus.Stopped && c++ < 5)\n                    {\n                        Thread.Sleep(1000);\n                        service = new ServiceController(\"MouseWithoutBordersSvc\");\n                    }\n\n                    if (string.IsNullOrWhiteSpace(desktopToRunMouseWithoutBordersOn))\n                    {\n                        startTag2 ??= Process.GetCurrentProcess().SessionId.ToString(CultureInfo.InvariantCulture);\n                        service.Start(new string[] { startTag1, startTag2 });\n                    }\n                    else\n                    {\n                        service.Start(new string[] { desktopToRunMouseWithoutBordersOn });\n                    }\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n\n                    // ERROR_SERVICE_ALREADY_RUNNING\n                    if (!(shownErrMessage || ((e?.InnerException as Win32Exception)?.NativeErrorCode == 1056)))\n                    {\n                        shownErrMessage = true;\n                        _ = MessageBox.Show(\n                            \"无法启动服务 \" + service.ServiceName + \": \" + e.Message,\n                            Common.BinaryName,\n                            MessageBoxButtons.OK,\n                            MessageBoxIcon.Error);\n                    }\n\n                    return;\n                }\n            });\n\n            // Wait for the task while not blocking the UI thread.\n            do\n            {\n                MMSleep(1);\n\n                if (task.IsCanceled || task.IsCompleted || task.IsFaulted)\n                {\n                    break;\n                }\n            }\n            while (true);\n        }\n\n        internal static void StartServiceAndSendLogoffSignal()\n        {\n            try\n            {\n                Process[] p = Process.GetProcessesByName(\"winlogon\");\n                Process me = Process.GetCurrentProcess();\n                string myWinlogon = p?.FirstOrDefault(item => item.SessionId == me.SessionId)?.Id.ToString(CultureInfo.InvariantCulture) ?? null;\n\n                if (string.IsNullOrWhiteSpace(myWinlogon))\n                {\n                    StartMouseWithoutBordersService(null, \"logoff\");\n                }\n                else\n                {\n                    StartMouseWithoutBordersService(null, \"logoff\", myWinlogon);\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log($\"{nameof(StartServiceAndSendLogoffSignal)}: {e.Message}\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/EasyMouseOption.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nnamespace MouseWithoutBorders.Class\n{\n    internal enum EasyMouseOption : int\n    {\n        关闭 = 0,\n        开启 = 1,\n        Ctrl = 2,\n        Shift = 3,\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Extensions.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.IO;\n\nusing MouseWithoutBorders.Core;\n\n// Disable the warning to preserve original code\n#pragma warning disable CA1716\nnamespace MouseWithoutBorders.Class\n#pragma warning restore CA1716\n{\n    internal static class Extensions\n    {\n        internal static int ReadEx(this Stream st, byte[] buf, int bufIndex, int length)\n        {\n            int bytesReceived = st.Read(buf, bufIndex, length);\n\n            int receivedCount = bytesReceived;\n\n            while (receivedCount != 0 && bytesReceived < length)\n            {\n                bytesReceived += receivedCount = st.Read(buf, bufIndex + bytesReceived, length - bytesReceived);\n            }\n\n            return bytesReceived;\n        }\n\n        internal static void KillProcess(this Process process, bool keepTrying = false)\n        {\n            string processName = process.ProcessName;\n            int processId = process.Id;\n\n            do\n            {\n                try\n                {\n                    process.Kill();\n                    break;\n                }\n                catch (Win32Exception e)\n                {\n                    string log = $\"The process {processName} (PID={processId}) could not be terminated, error: {e.Message}\";\n                    string logcn = $\"进程 {processName} (PID={processId}) 无法被终止，错误: {e.Message}\";\n                    Logger.TelemetryLogTrace(log, SeverityLevel.Error);\n                    Common.ShowToolTip(logcn, 5000);\n\n                    if (!keepTrying)\n                    {\n                        Thread.Sleep(1000);\n                        break;\n                    }\n                }\n            }\n            while (true);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/IClipboardHelper.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing System.IO.Pipes;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Security.AccessControl;\nusing System.Security.Principal;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nusing Microsoft.VisualStudio.Threading;\nusing Newtonsoft.Json;\nusing StreamJsonRpc;\n\n#if !MM_HELPER\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\n#endif\n\nusing SystemClipboard = System.Windows.Forms.Clipboard;\n#if !MM_HELPER\nusing Thread = MouseWithoutBorders.Core.Thread;\n#endif\n\nnamespace MouseWithoutBorders\n{\n    [JsonObject(MemberSerialization.OptIn)]\n    public struct ByteArrayOrString\n    {\n        private enum ValueType\n        {\n            ByteArray,\n            String,\n        }\n\n        [JsonProperty]\n        private ValueType _type;\n\n        private byte[] _byteArrayValue;\n        private string _stringValue;\n\n        public ByteArrayOrString(byte[] byteArray)\n        {\n            _type = ValueType.ByteArray;\n            _byteArrayValue = byteArray;\n            _stringValue = null;\n        }\n\n        public ByteArrayOrString(string str)\n        {\n            _type = ValueType.String;\n            _byteArrayValue = null;\n            _stringValue = str;\n        }\n\n        public bool IsByteArray => _type == ValueType.ByteArray;\n\n        public bool IsString => _type == ValueType.String;\n\n        [JsonProperty(\"byteArray\")]\n        public byte[] ByteArray\n        {\n            get => _byteArrayValue;\n            set\n            {\n                _byteArrayValue = value;\n                _type = ValueType.ByteArray;\n            }\n        }\n\n        [JsonProperty(\"string\")]\n        public string TheString\n        {\n            get => _stringValue;\n            set\n            {\n                _stringValue = value;\n                _type = ValueType.String;\n            }\n        }\n\n        public bool ShouldSerializeByteArray() => IsByteArray;\n\n        public bool ShouldSerializeString() => IsString;\n\n        public byte[] GetByteArray()\n        {\n            if (IsByteArray)\n            {\n                return _byteArrayValue;\n            }\n\n            throw new InvalidOperationException(\"The value is not a byte array.\");\n        }\n\n        public string GetString()\n        {\n            if (IsString)\n            {\n                return _stringValue;\n            }\n\n            throw new InvalidOperationException(\"The value is not a string.\");\n        }\n\n        public static implicit operator ByteArrayOrString(byte[] byteArray) => new ByteArrayOrString(byteArray);\n\n        public static implicit operator ByteArrayOrString(string str) => new ByteArrayOrString(str);\n    }\n\n    public interface IClipboardHelper\n    {\n        void SendLog(string log);\n\n        void SendDragFile(string fileName);\n\n        void SendClipboardData(ByteArrayOrString data, bool isFilePath);\n    }\n\n#if !MM_HELPER\n    public class ClipboardHelper : IClipboardHelper\n    {\n        public void SendLog(string log)\n        {\n            Logger.LogDebug(\"FROM HELPER: \" + log);\n\n            if (!string.IsNullOrEmpty(log))\n            {\n                if (log.StartsWith(\"Screen capture ended\", StringComparison.InvariantCulture))\n                {\n                    /* TODO: Telemetry for screen capture. */\n\n                    if (Setting.Values.FirstCtrlShiftS)\n                    {\n                        Setting.Values.FirstCtrlShiftS = false;\n                        Common.ShowToolTip(\"区块截屏被触发，您可以在设置中调整快捷键.\", 10000);\n                    }\n                }\n                else if (log.StartsWith(\"Trace:\", StringComparison.InvariantCulture))\n                {\n                    Logger.TelemetryLogTrace(log, SeverityLevel.Information);\n                }\n            }\n        }\n\n        public void SendDragFile(string fileName)\n        {\n            Common.DragDropStep05Ex(fileName);\n        }\n\n        public void SendClipboardData(ByteArrayOrString data, bool isFilePath)\n        {\n            _ = Common.CheckClipboardEx(data, isFilePath);\n        }\n    }\n#endif\n\n    internal sealed class IpcChannel<T>\n        where T : new()\n    {\n        public static T StartIpcServer(string pipeName, CancellationToken cancellationToken)\n        {\n            SecurityIdentifier securityIdentifier = new SecurityIdentifier(\nWellKnownSidType.AuthenticatedUserSid, null);\n\n            PipeSecurity pipeSecurity = new PipeSecurity();\n            pipeSecurity.AddAccessRule(new PipeAccessRule(\n                securityIdentifier,\n                PipeAccessRights.ReadWrite | PipeAccessRights.CreateNewInstance,\n                AccessControlType.Allow));\n\n            _ = Task.Factory.StartNew(\n                async () =>\n                {\n                    try\n                    {\n                        while (!cancellationToken.IsCancellationRequested)\n                        {\n                            using (var serverChannel = NamedPipeServerStreamAcl.Create(pipeName, PipeDirection.InOut, NamedPipeServerStream.MaxAllowedServerInstances, PipeTransmissionMode.Byte, PipeOptions.Asynchronous, 0, 0, pipeSecurity))\n                            {\n                                await serverChannel.WaitForConnectionAsync();\n                                var taskRpc = JsonRpc.Attach(serverChannel, new T());\n                                await taskRpc.Completion;\n                            }\n                        }\n                    }\n                    catch (OperationCanceledException)\n                    {\n                    }\n                    catch (Exception e)\n                    {\n#if MM_HELPER\n                        _ = e;\n#else\n                        Logger.Log(e);\n#endif\n                    }\n                },\n                cancellationToken,\n                TaskCreationOptions.None,\n                TaskScheduler.Default);\n\n            return default(T);\n        }\n    }\n\n    internal sealed class IpcHelper\n    {\n        private const string ChannelName = \"MouseWithoutBorders\";\n        private const string RemoteObjectName = \"ClipboardHelper\";\n\n#if !MM_HELPER\n        private static void CleanupStream()\n        {\n            if (_serverTaskCancellationSource != null)\n            {\n                _serverTaskCancellationSource.Cancel();\n                _serverTaskCancellationSource.Dispose();\n                _serverTaskCancellationSource = null;\n            }\n        }\n\n        private static CancellationTokenSource _serverTaskCancellationSource;\n\n        internal static void CreateIpcServer(bool cleanup)\n        {\n            try\n            {\n                if (cleanup)\n                {\n                    CleanupStream();\n                    return;\n                }\n\n                _serverTaskCancellationSource = new CancellationTokenSource();\n                CancellationToken cancellationToken = _serverTaskCancellationSource.Token;\n\n                IpcChannel<ClipboardHelper>.StartIpcServer(ChannelName + \"/\" + RemoteObjectName, cancellationToken);\n                Common.IpcChannelCreated = true;\n            }\n            catch (Exception e)\n            {\n                Common.IpcChannelCreated = false;\n                Common.ShowToolTip(\"Error setting up clipboard sharing, clipboard sharing will not work!\", 5000, ToolTipIcon.Error);\n                Logger.Log(e);\n            }\n        }\n#else\n        internal static IClipboardHelper CreateIpcClient()\n        {\n            try\n            {\n                var stream = new NamedPipeClientStream(\".\", ChannelName + \"/\" + RemoteObjectName, PipeDirection.InOut, PipeOptions.Asynchronous);\n\n                stream.Connect();\n\n                return JsonRpc.Attach<IClipboardHelper>(stream);\n            }\n            catch (Exception e)\n            {\n                EventLogger.LogEvent(e.Message, EventLogEntryType.Error);\n            }\n\n            return null;\n        }\n#endif\n\n    }\n\n    internal static class EventLogger\n    {\n#if MM_HELPER\n        private const string EventSourceName = \"MouseWithoutBordersHelper\";\n#else\n        private const string EventSourceName = \"MouseWithoutBorders\";\n#endif\n\n        internal static void LogEvent(string message, EventLogEntryType logType = EventLogEntryType.Information)\n        {\n            try\n            {\n                if (!EventLog.SourceExists(EventSourceName))\n                {\n                    EventLog.CreateEventSource(EventSourceName, \"Application\");\n                }\n\n                EventLog.WriteEntry(EventSourceName, message, logType);\n            }\n            catch (Exception e)\n            {\n                Debug.WriteLine(message + \": \" + e.Message);\n            }\n        }\n    }\n#if MM_HELPER\n\n    internal static class ClipboardMMHelper\n    {\n        internal static IntPtr NextClipboardViewer = IntPtr.Zero;\n        private static FormHelper helperForm;\n        private static bool addClipboardFormatListenerResult;\n\n        private static void Log(string log)\n        {\n            helperForm.SendLog(log);\n        }\n\n        private static void Log(Exception e)\n        {\n            Log($\"Trace: {e}\");\n        }\n\n        internal static void HookClipboard(FormHelper f)\n        {\n            helperForm = f;\n\n            try\n            {\n                addClipboardFormatListenerResult = NativeMethods.AddClipboardFormatListener(f.Handle);\n\n                int err = addClipboardFormatListenerResult ? 0 : Marshal.GetLastWin32Error();\n\n                if (err != 0)\n                {\n                    Log($\"Trace: {nameof(NativeMethods.AddClipboardFormatListener)}: GetLastError = {err}\");\n                }\n            }\n            catch (EntryPointNotFoundException e)\n            {\n                Log($\"{nameof(NativeMethods.AddClipboardFormatListener)} is unavailable in this version of Windows.\");\n                Log(e);\n            }\n            catch (Exception e)\n            {\n                Log(e);\n            }\n\n            // Fallback\n            if (!addClipboardFormatListenerResult)\n            {\n                NextClipboardViewer = NativeMethods.SetClipboardViewer(f.Handle);\n                int err = NextClipboardViewer == IntPtr.Zero ? Marshal.GetLastWin32Error() : 0;\n\n                if (err != 0)\n                {\n                    Log($\"Trace: {nameof(NativeMethods.SetClipboardViewer)}: GetLastError = {err}\");\n                }\n            }\n\n            Log($\"Trace: Clipboard monitor method {(addClipboardFormatListenerResult ? nameof(NativeMethods.AddClipboardFormatListener) : NextClipboardViewer != IntPtr.Zero ? nameof(NativeMethods.SetClipboardViewer) : \"(none)\")} is used.\");\n        }\n\n        internal static void UnhookClipboard()\n        {\n            if (addClipboardFormatListenerResult)\n            {\n                addClipboardFormatListenerResult = false;\n                _ = NativeMethods.RemoveClipboardFormatListener(helperForm.Handle);\n            }\n            else\n            {\n                _ = NativeMethods.ChangeClipboardChain(helperForm.Handle, NextClipboardViewer);\n                NextClipboardViewer = IntPtr.Zero;\n            }\n        }\n\n        private static void ReHookClipboard()\n        {\n            UnhookClipboard();\n            HookClipboard(helperForm);\n        }\n\n        internal static bool UpdateNextClipboardViewer(Message m)\n        {\n            if (m.WParam == NextClipboardViewer)\n            {\n                NextClipboardViewer = m.LParam;\n                return true;\n            }\n\n            return false;\n        }\n\n        internal static void PassMessageToTheNextViewer(Message m)\n        {\n            if (NextClipboardViewer != IntPtr.Zero && NextClipboardViewer != helperForm.Handle)\n            {\n                _ = NativeMethods.SendMessage(NextClipboardViewer, m.Msg, m.WParam, m.LParam);\n            }\n        }\n\n        public static bool ContainsFileDropList()\n        {\n            bool rv = false;\n\n            try\n            {\n                rv = Common.Retry(nameof(SystemClipboard.ContainsFileDropList), () => { return SystemClipboard.ContainsFileDropList(); }, (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n\n            return rv;\n        }\n\n        public static bool ContainsImage()\n        {\n            bool rv = false;\n\n            try\n            {\n                rv = Common.Retry(nameof(SystemClipboard.ContainsImage), () => { return SystemClipboard.ContainsImage(); }, (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n\n            return rv;\n        }\n\n        public static bool ContainsText()\n        {\n            bool rv = false;\n\n            try\n            {\n                rv = Common.Retry(nameof(SystemClipboard.ContainsText), () => { return SystemClipboard.ContainsText(); }, (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n\n            return rv;\n        }\n\n        public static StringCollection GetFileDropList()\n        {\n            StringCollection rv = null;\n\n            try\n            {\n                rv = Common.Retry(nameof(SystemClipboard.GetFileDropList), () => { return SystemClipboard.GetFileDropList(); }, (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n\n            return rv;\n        }\n\n        public static Image GetImage()\n        {\n            Image rv = null;\n\n            try\n            {\n                rv = Common.Retry(nameof(SystemClipboard.GetImage), () => { return SystemClipboard.GetImage(); }, (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n\n            return rv;\n        }\n\n        public static string GetText(TextDataFormat format)\n        {\n            string rv = null;\n\n            try\n            {\n                rv = Common.Retry(nameof(SystemClipboard.GetText), () => { return SystemClipboard.GetText(format); }, (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (System.ComponentModel.InvalidEnumArgumentException e)\n            {\n                Log(e);\n            }\n\n            return rv;\n        }\n\n        public static void SetImage(Image image)\n        {\n            try\n            {\n                _ = Common.Retry(\n                    nameof(SystemClipboard.SetImage),\n                    () =>\n                {\n                    SystemClipboard.SetImage(image);\n                    return true;\n                },\n                    (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ArgumentNullException e)\n            {\n                Log(e);\n            }\n        }\n\n        public static void SetText(string text)\n        {\n            try\n            {\n                _ = Common.Retry(\n                    nameof(SystemClipboard.SetText),\n                    () =>\n                {\n                    SystemClipboard.SetText(text);\n                    return true;\n                },\n                    (log) => Log(log));\n            }\n            catch (ExternalException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ThreadStateException e)\n            {\n                Log(e);\n                ReHookClipboard();\n            }\n            catch (ArgumentNullException e)\n            {\n                Log(e);\n            }\n        }\n    }\n\n#endif\n\n    internal sealed class SharedConst\n    {\n        internal const int QUIT_CMD = 0x409;\n    }\n\n    internal sealed partial class Common\n    {\n        internal static bool IpcChannelCreated { get; set; }\n\n        internal static T Retry<T>(string name, Func<T> func, Action<string> log, Action preRetry = null)\n        {\n            int count = 0;\n\n            do\n            {\n                try\n                {\n                    T rv = func();\n\n                    if (count > 0)\n                    {\n                        log($\"Trace: {name} has been successful after {count} retry.\");\n                    }\n\n                    return rv;\n                }\n                catch (Exception)\n                {\n                    count++;\n\n                    preRetry?.Invoke();\n\n                    if (count > 10)\n                    {\n                        throw;\n                    }\n\n                    Application.DoEvents();\n                    Thread.Sleep(200);\n                }\n            }\n            while (true);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/InputHook.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\n// <summary>\n//     Keyboard/Mouse hook callbacks, pre-process before calling to routines in Common.Event.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Windows.Forms;\n\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing MouseWithoutBorders.Core;\n\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.InputHook.#MouseHookProc(System.Int32,System.Int32,System.IntPtr)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Scope = \"member\", Target = \"MouseWithoutBorders.InputHook.#ProcessKeyEx(System.Int32,System.Int32)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1300:SpecifyMessageBoxOptions\", Scope = \"member\", Target = \"MouseWithoutBorders.InputHook.#Start()\", Justification = \"Dotnet port with style preservation\")]\n\nnamespace MouseWithoutBorders.Class\n{\n    internal class InputHook\n    {\n        internal delegate void MouseEvHandler(MOUSEDATA e, int dx, int dy);\n\n        internal delegate void KeybdEvHandler(KEYBDDATA e);\n\n        [StructLayout(LayoutKind.Sequential)]\n        private struct MouseHookStruct\n        {\n            internal NativeMethods.POINT Pt;\n            internal int Hwnd;\n            internal int WHitTestCode;\n            internal int DwExtraInfo;\n        }\n\n        // http://msdn.microsoft.com/en-us/library/ms644970(VS.85).aspx\n        [StructLayout(LayoutKind.Sequential)]\n        private struct MouseLLHookStruct\n        {\n            internal NativeMethods.POINT Pt;\n            internal int MouseData;\n            internal int Flags;\n            internal int Time;\n            internal int DwExtraInfo;\n        }\n\n        [StructLayout(LayoutKind.Sequential)]\n        private struct KeyboardHookStruct\n        {\n            internal int VkCode;\n            internal int ScanCode;\n            internal int Flags;\n            internal int Time;\n            internal int DwExtraInfo;\n        }\n\n        internal event MouseEvHandler MouseEvent;\n\n        internal event KeybdEvHandler KeyboardEvent;\n\n        private int hMouseHook;\n        private int hKeyboardHook;\n        private static NativeMethods.HookProc mouseHookProcedure;\n        private static NativeMethods.HookProc keyboardHookProcedure;\n\n        private static MouseLLHookStruct mouseHookStruct;\n        private static KeyboardHookStruct keyboardHookStruct;\n        private static MOUSEDATA hookCallbackMouseData;\n        private static KEYBDDATA hookCallbackKeybdData;\n\n        private static bool winDown;\n        private static bool altDown;\n        private static bool shiftDown;\n\n        internal static bool RealData { get; set; } = true;\n\n        internal static int SkipMouseUpCount { get; set; }\n\n        internal static bool SkipMouseUpDown { get; set; }\n\n        internal static bool CtrlDown { get; private set; }\n\n        internal static bool EasyMouseKeyDown { get; set; }\n\n        internal InputHook()\n        {\n            Start();\n        }\n\n        ~InputHook()\n        {\n            Stop();\n        }\n\n        internal void Start()\n        {\n            int le;\n            bool er = false;\n\n            // Install Mouse Hook\n            mouseHookProcedure = new NativeMethods.HookProc(MouseHookProc);\n            hMouseHook = NativeMethods.SetWindowsHookEx(\n                Common.WH_MOUSE_LL,\n                mouseHookProcedure,\n                Marshal.GetHINSTANCE(\n                    Assembly.GetExecutingAssembly().GetModules()[0]),\n                0);\n\n            if (hMouseHook == 0)\n            {\n                le = Marshal.GetLastWin32Error();\n                Logger.Log(\"Error installing Mouse hook: \" + le.ToString(CultureInfo.CurrentCulture));\n                er = true;\n                Stop();\n            }\n\n            // Install Keyboard Hook\n            keyboardHookProcedure = new NativeMethods.HookProc(KeyboardHookProc);\n            hKeyboardHook = NativeMethods.SetWindowsHookEx(\n                Common.WH_KEYBOARD_LL,\n                keyboardHookProcedure,\n                Marshal.GetHINSTANCE(\n                Assembly.GetExecutingAssembly().GetModules()[0]),\n                0);\n            if (hKeyboardHook == 0)\n            {\n                le = Marshal.GetLastWin32Error();\n                Logger.Log(\"Error installing keyboard hook: \" + le.ToString(CultureInfo.CurrentCulture));\n                er = true;\n                Stop();\n            }\n\n            if (er)\n            {\n                if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                {\n                    _ = MessageBox.Show(\n                        \"安装键盘/鼠标侦听器失败！\",\n                        Application.ProductName,\n                        MessageBoxButtons.OK,\n                        MessageBoxIcon.Error);\n                }\n            }\n            else\n            {\n                Common.InitLastInputEventCount();\n            }\n        }\n\n        internal void Stop()\n        {\n            if (hMouseHook != 0)\n            {\n                int retMouse = NativeMethods.UnhookWindowsHookEx(hMouseHook);\n                hMouseHook = 0;\n                if (retMouse == 0)\n                {\n                    int errorCode = Marshal.GetLastWin32Error();\n\n                    // throw new Win32Exception(errorCode);\n                    Logger.Log(\"Exception uninstalling Mouse hook, error code: \" + errorCode.ToString(CultureInfo.CurrentCulture));\n                }\n            }\n\n            if (hKeyboardHook != 0)\n            {\n                int retKeyboard = NativeMethods.UnhookWindowsHookEx(hKeyboardHook);\n                hKeyboardHook = 0;\n                if (retKeyboard == 0)\n                {\n                    int errorCode = Marshal.GetLastWin32Error();\n\n                    // throw new Win32Exception(errorCode);\n                    Logger.Log(\"Exception uninstalling keyboard hook, error code: \" + errorCode.ToString(CultureInfo.CurrentCulture));\n                }\n            }\n        }\n\n        // Better performance, compared to Marshal.PtrToStructure.\n        private static MouseLLHookStruct LParamToMouseLLHookStruct(IntPtr lParam)\n        {\n            unsafe\n            {\n                return *(MouseLLHookStruct*)lParam;\n            }\n        }\n\n        private static KeyboardHookStruct LParamToKeyboardHookStruct(IntPtr lParam)\n        {\n            unsafe\n            {\n                return *(KeyboardHookStruct*)lParam;\n            }\n        }\n\n        private int MouseHookProc(int nCode, int wParam, IntPtr lParam)\n        {\n            int rv = 1, dx = 0, dy = 0;\n            bool local = false;\n            Common.InputEventCount++;\n\n            try\n            {\n                if (!RealData)\n                {\n                    RealData = true;\n\n                    // Common.Log(\"MouseHookProc: Not real data!\");\n                    // return rv;\n                    rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);\n                }\n                else\n                {\n                    Common.RealInputEventCount++;\n\n                    if (Common.NewDesMachineID == Common.MachineID || Common.NewDesMachineID == ID.ALL)\n                    {\n                        local = true;\n                        if (Common.MainFormVisible && !Common.IsDropping)\n                        {\n                            Common.MainFormDot();\n                        }\n                    }\n\n                    if (nCode >= 0 && MouseEvent != null)\n                    {\n                        if (wParam == Common.WM_LBUTTONUP && SkipMouseUpCount > 0)\n                        {\n                            Logger.LogDebug($\"{nameof(SkipMouseUpCount)}: {SkipMouseUpCount}.\");\n                            SkipMouseUpCount--;\n                            rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);\n                            return rv;\n                        }\n\n                        if ((wParam == Common.WM_LBUTTONUP || wParam == Common.WM_LBUTTONDOWN) && SkipMouseUpDown)\n                        {\n                            rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);\n                            return rv;\n                        }\n\n                        mouseHookStruct = LParamToMouseLLHookStruct(lParam);\n                        hookCallbackMouseData.dwFlags = wParam;\n\n                        // Use WheelDelta to store XBUTTON1/XBUTTON2 data.\n                        hookCallbackMouseData.WheelDelta = (short)((mouseHookStruct.MouseData >> 16) & 0xffff);\n\n                        if (local)\n                        {\n                            hookCallbackMouseData.X = mouseHookStruct.Pt.x;\n                            hookCallbackMouseData.Y = mouseHookStruct.Pt.y;\n\n                            if (Setting.Values.DrawMouse && Common.MouseCursorForm != null)\n                            {\n                                CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);\n                            }\n                        }\n                        else\n                        {\n                            if (Common.SwitchLocation.Count > 0 && Common.NewDesMachineID != Common.MachineID && Common.NewDesMachineID != ID.ALL)\n                            {\n                                Common.SwitchLocation.Count--;\n\n                                if (Common.SwitchLocation.X > Common.XY_BY_PIXEL - 100000 || Common.SwitchLocation.Y > Common.XY_BY_PIXEL - 100000)\n                                {\n                                    hookCallbackMouseData.X = Common.SwitchLocation.X - Common.XY_BY_PIXEL;\n                                    hookCallbackMouseData.Y = Common.SwitchLocation.Y - Common.XY_BY_PIXEL;\n                                }\n                                else\n                                {\n                                    hookCallbackMouseData.X = (Common.SwitchLocation.X * Common.ScreenWidth / 65535) + Common.PrimaryScreenBounds.Left;\n                                    hookCallbackMouseData.Y = (Common.SwitchLocation.Y * Common.ScreenHeight / 65535) + Common.PrimaryScreenBounds.Top;\n                                }\n\n                                Common.HideMouseCursor(false);\n                            }\n                            else\n                            {\n                                dx = mouseHookStruct.Pt.x - Common.LastPos.X;\n                                dy = mouseHookStruct.Pt.y - Common.LastPos.Y;\n\n                                hookCallbackMouseData.X += dx;\n                                hookCallbackMouseData.Y += dy;\n\n                                if (hookCallbackMouseData.X < Common.PrimaryScreenBounds.Left)\n                                {\n                                    hookCallbackMouseData.X = Common.PrimaryScreenBounds.Left - 1;\n                                }\n                                else if (hookCallbackMouseData.X > Common.PrimaryScreenBounds.Right)\n                                {\n                                    hookCallbackMouseData.X = Common.PrimaryScreenBounds.Right + 1;\n                                }\n\n                                if (hookCallbackMouseData.Y < Common.PrimaryScreenBounds.Top)\n                                {\n                                    hookCallbackMouseData.Y = Common.PrimaryScreenBounds.Top - 1;\n                                }\n                                else if (hookCallbackMouseData.Y > Common.PrimaryScreenBounds.Bottom)\n                                {\n                                    hookCallbackMouseData.Y = Common.PrimaryScreenBounds.Bottom + 1;\n                                }\n\n                                dx += dx < 0 ? -Common.MOVE_MOUSE_RELATIVE : Common.MOVE_MOUSE_RELATIVE;\n                                dy += dy < 0 ? -Common.MOVE_MOUSE_RELATIVE : Common.MOVE_MOUSE_RELATIVE;\n                            }\n                        }\n\n                        MouseEvent(hookCallbackMouseData, dx, dy);\n\n                        Common.DragDropStep01(wParam);\n                        Common.DragDropStep09(wParam);\n                    }\n\n                    if (local)\n                    {\n                        rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);\n                    }\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n                rv = NativeMethods.CallNextHookEx(hMouseHook, nCode, wParam, lParam);\n            }\n\n            return rv;\n        }\n\n        private int KeyboardHookProc(int nCode, int wParam, IntPtr lParam)\n        {\n            Common.InputEventCount++;\n            if (!RealData)\n            {\n                return NativeMethods.CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);\n            }\n\n            Common.RealInputEventCount++;\n\n            keyboardHookStruct = LParamToKeyboardHookStruct(lParam);\n            hookCallbackKeybdData.dwFlags = keyboardHookStruct.Flags;\n            hookCallbackKeybdData.wVk = (short)keyboardHookStruct.VkCode;\n\n            if (nCode >= 0 && KeyboardEvent != null)\n            {\n                if (!ProcessKeyEx(keyboardHookStruct.VkCode, keyboardHookStruct.Flags, hookCallbackKeybdData))\n                {\n                    return 1;\n                }\n\n                KeyboardEvent(hookCallbackKeybdData);\n            }\n\n            if (Common.DesMachineID == ID.NONE || Common.DesMachineID == ID.ALL || Common.DesMachineID == Common.MachineID)\n            {\n                return NativeMethods.CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);\n            }\n            else\n            {\n                return 1;\n            }\n        }\n\n        private bool ProcessKeyEx(int vkCode, int flags, KEYBDDATA hookCallbackKeybdData)\n        {\n            if ((flags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)\n            {\n                EasyMouseKeyDown = false;\n\n                switch ((VK)vkCode)\n                {\n                    case VK.LWIN:\n                    case VK.RWIN:\n                        winDown = false;\n                        break;\n\n                    case VK.LCONTROL:\n                    case VK.RCONTROL:\n                        CtrlDown = false;\n                        break;\n\n                    case VK.LMENU:\n                    case VK.RMENU:\n                        altDown = false;\n                        break;\n\n                    case VK.LSHIFT:\n                        shiftDown = false;\n                        break;\n\n                    default:\n                        break;\n                }\n            }\n            else\n            {\n                UpdateEasyMouseKeyDown((VK)vkCode);\n\n                switch ((VK)vkCode)\n                {\n                    case VK.LWIN:\n                    case VK.RWIN:\n                        winDown = true;\n                        break;\n\n                    case VK.LCONTROL:\n                    case VK.RCONTROL:\n                        CtrlDown = true;\n                        break;\n\n                    case VK.LMENU:\n                    case VK.RMENU:\n                        altDown = true;\n                        break;\n\n                    case VK.LSHIFT:\n                        shiftDown = true;\n                        break;\n\n                    case VK.DELETE:\n                        if (CtrlDown && altDown)\n                        {\n                            CtrlDown = altDown = false;\n                            KeyboardEvent(hookCallbackKeybdData);\n\n                            if (Common.DesMachineID != ID.ALL)\n                            {\n                                Common.SwitchToMachine(Common.MachineName.Trim());\n                            }\n\n                            /*\n#if CUSTOMIZE_LOGON_SCREEN\n                           Common.DoSomethingInUIThread(delegate()\n                           {\n                               Common.MainForm.LoadNewLogonBackground();\n                           });\n#endif\n* */\n                        }\n\n                        break;\n\n                    case VK.ESCAPE:\n                        if (Common.IsTopMostMessageNotNull())\n                        {\n                            Common.HideTopMostMessage();\n                        }\n\n                        break;\n\n                    default:\n                        Logger.LogDebug(\"X\");\n                        return ProcessHotKeys(vkCode, hookCallbackKeybdData);\n                }\n            }\n\n            return true;\n        }\n\n        private void UpdateEasyMouseKeyDown(VK vkCode)\n        {\n            EasyMouseOption easyMouseOption = (EasyMouseOption)Setting.Values.EasyMouse;\n\n            EasyMouseKeyDown = (easyMouseOption == EasyMouseOption.Ctrl && (vkCode == VK.LCONTROL || vkCode == VK.RCONTROL))\n                || (easyMouseOption == EasyMouseOption.Shift && (vkCode == VK.LSHIFT || vkCode == VK.RSHIFT));\n        }\n\n        private static long lastHotKeyLockMachine;\n\n        private void ResetModifiersState(HotkeySettings matchingHotkey)\n        {\n            CtrlDown = CtrlDown && matchingHotkey.Ctrl;\n            altDown = altDown && matchingHotkey.Alt;\n            shiftDown = shiftDown && matchingHotkey.Shift;\n            winDown = winDown && matchingHotkey.Win;\n        }\n\n        private List<short> GetVkCodesList(HotkeySettings hotkey)\n        {\n            var list = new List<short>();\n            if (hotkey.Alt)\n            {\n                list.Add((short)VK.MENU);\n            }\n\n            if (hotkey.Shift)\n            {\n                list.Add((short)VK.SHIFT);\n            }\n\n            if (hotkey.Win)\n            {\n                list.Add((short)VK.LWIN);\n            }\n\n            if (hotkey.Ctrl)\n            {\n                list.Add((short)VK.CONTROL);\n            }\n\n            if (hotkey.Code != 0)\n            {\n                list.Add((short)hotkey.Code);\n            }\n\n            return list;\n        }\n\n        private bool ProcessHotKeys(int vkCode, KEYBDDATA hookCallbackKeybdData)\n        {\n            if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeySwitch2AllPC))\n            {\n                ResetLastSwitchKeys();\n                Common.SwitchToMultipleMode(Common.DesMachineID != ID.ALL, true);\n            }\n\n            if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeyToggleEasyMouse))\n            {\n                if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                {\n                    EasyMouseOption easyMouseOption = (EasyMouseOption)Setting.Values.EasyMouse;\n\n                    if (easyMouseOption is EasyMouseOption.关闭 or EasyMouseOption.开启)\n                    {\n                        Setting.Values.EasyMouse = (int)(easyMouseOption == EasyMouseOption.关闭 ? EasyMouseOption.开启 : EasyMouseOption.关闭);\n\n                        Common.ShowToolTip($\"易动模式已通过快捷键切换为 [{(EasyMouseOption)Setting.Values.EasyMouse}]. 可以在设置中调整快捷键.\", 5000);\n                        return false;\n                    }\n                }\n            }\n            else if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeyLockMachine))\n            {\n                if (!Common.RunOnLogonDesktop\n                    && !Common.RunOnScrSaverDesktop)\n                {\n                    if (Common.GetTick() - lastHotKeyLockMachine < 500)\n                    {\n                        Common.SwitchToMultipleMode(true, true);\n\n                        var codes = GetVkCodesList(Setting.Values.HotKeyLockMachine);\n\n                        foreach (var code in codes)\n                        {\n                            hookCallbackKeybdData.wVk = code;\n                            KeyboardEvent(hookCallbackKeybdData);\n                        }\n\n                        hookCallbackKeybdData.dwFlags |= (int)Common.LLKHF.UP;\n\n                        foreach (var code in codes)\n                        {\n                            hookCallbackKeybdData.wVk = code;\n                            KeyboardEvent(hookCallbackKeybdData);\n                        }\n\n                        Common.SwitchToMultipleMode(false, true);\n\n                        _ = NativeMethods.LockWorkStation();\n                    }\n                    else\n                    {\n                        KeyboardEvent(hookCallbackKeybdData);\n                    }\n\n                    lastHotKeyLockMachine = Common.GetTick();\n\n                    return false;\n                }\n            }\n            else if (Common.HotkeyMatched(vkCode, winDown, CtrlDown, altDown, shiftDown, Setting.Values.HotKeyReconnect))\n            {\n                Common.ShowToolTip(\"正在重新连接...\", 2000);\n                Common.LastReconnectByHotKeyTime = Common.GetTick();\n                Common.PleaseReopenSocket = Common.REOPEN_WHEN_HOTKEY;\n                return false;\n            }\n\n            if (CtrlDown && altDown)\n            {\n                if (shiftDown && vkCode == Setting.Values.HotKeyExitMM &&\n                    (Common.DesMachineID == Common.MachineID || Common.DesMachineID == ID.ALL))\n                {\n                    Common.DoSomethingInUIThread(() =>\n                    {\n                        Common.MainForm.NotifyIcon.Visible = false;\n\n                        for (int i = 1; i < 10; i++)\n                        {\n                            Application.DoEvents();\n                            Thread.Sleep(20);\n                        }\n\n                        Common.MainForm.Quit(false, false);\n                    });\n                }\n                else if (shiftDown || winDown)\n                {\n                    // The following else cases should work if control and alt modifiers are pressed. The hotkeys should still be captured.\n                    // But if any of the other 2 modifiers (shift or win) are pressed, they hotkeys should not be activated.\n                    // Issue #26597\n                    return true;\n                }\n                else if (vkCode == Setting.Values.HotKeySwitchMachine ||\n                     vkCode == Setting.Values.HotKeySwitchMachine + 1 ||\n                     vkCode == Setting.Values.HotKeySwitchMachine + 2 ||\n                     vkCode == Setting.Values.HotKeySwitchMachine + 3)\n                {\n                    if (Switch2(vkCode - Setting.Values.HotKeySwitchMachine))\n                    {\n                        return false;\n                    }\n                }\n            }\n\n            return true;\n        }\n\n        private static bool Switch2(int index)\n        {\n            if (Common.MachineMatrix != null && Common.MachineMatrix.Length > index)\n            {\n                string mcName = Common.MachineMatrix[index].Trim();\n                if (!string.IsNullOrEmpty(mcName))\n                {\n                    // Common.DoSomethingInUIThread(delegate()\n                    {\n                        Common.ReleaseAllKeys();\n                    }\n\n                    // );\n                    Common.SwitchToMachine(mcName);\n\n                    if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                    {\n                        Common.ShowToolTip(\n                            string.Format(\n                                CultureInfo.CurrentCulture,\n                                \"控制已通过快捷键 Ctrl+Alt+{1}{2} 切换到设备 {0}.\",\n                                mcName,\n                                Setting.Values.HotKeySwitchMachine == (int)VK.F1 ? \"F\" : string.Empty,\n                                index + 1),\n                            3000);\n                    }\n\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        internal void ResetLastSwitchKeys()\n        {\n            CtrlDown = winDown = altDown = false;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/Program.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\n// <summary>\n//     Application entry and pre-process/initialization.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Drawing.Printing;\nusing System.Globalization;\nusing System.IO;\nusing System.IO.Pipes;\nusing System.Linq;\nusing System.Security.Authentication.ExtendedProtection;\nusing System.Security.Principal;\nusing System.ServiceModel.Channels;\nusing System.ServiceProcess;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing System.Xml.Linq;\n\nusing ManagedCommon;\nusing Microsoft.PowerToys.Settings.UI.Library.Utilities;\nusing Microsoft.PowerToys.Telemetry;\nusing Newtonsoft.Json;\nusing StreamJsonRpc;\n\nusing Logger = MouseWithoutBorders.Core.Logger;\nusing Thread = MouseWithoutBorders.Core.Thread;\n\n[module: SuppressMessage(\"Microsoft.MSInternal\", \"CA904:DeclareTypesInMicrosoftOrSystemNamespace\", Scope = \"namespace\", Target = \"MouseWithoutBorders\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1014:MarkAssembliesWithClsCompliant\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1304:SpecifyCultureInfo\", Scope = \"member\", Target = \"MouseWithoutBorders.Program.#Main()\", MessageId = \"System.String.ToLower\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1300:SpecifyMessageBoxOptions\", Scope = \"member\", Target = \"MouseWithoutBorders.Program.#Main()\", Justification = \"Dotnet port with style preservation\")]\n\nnamespace MouseWithoutBorders.Class\n{\n    internal static class Program\n    {\n        private static readonly string ServiceName = \"PowerToys.MWB.Service\";\n\n        private static readonly string ServiceModeArg = \"UseService\";\n\n        public static bool ShowServiceModeErrorTooltip;\n\n        [STAThread]\n        private static void Main()\n        {\n            ManagedCommon.Logger.InitializeLogger(\"\\\\MouseWithoutBorders\\\\Logs\");\n            Logger.Log(Application.ProductName + \" Started!\");\n\n            ETWTrace etwTrace = new ETWTrace();\n\n            if (PowerToys.GPOWrapper.GPOWrapper.GetConfiguredMouseWithoutBordersEnabledValue() == PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)\n            {\n                Logger.Log(\"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.\");\n                return;\n            }\n\n            Thread.CurrentThread.Name = Application.ProductName + \" main thread\";\n            Common.BinaryName = Path.GetFileNameWithoutExtension(Application.ExecutablePath);\n\n            WindowsIdentity currentUser = WindowsIdentity.GetCurrent();\n            SecurityIdentifier currentUserSID = currentUser.User;\n            SecurityIdentifier localSystemSID = new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null);\n\n            bool runningAsSystem = currentUserSID.Equals(localSystemSID);\n            Common.RunWithNoAdminRight = !runningAsSystem;\n            try\n            {\n                string[] args = Environment.GetCommandLineArgs();\n\n                string firstArg = string.Empty;\n                if (args.Length > 1 && args[1] != null)\n                {\n                    firstArg = args[1].Trim();\n                }\n\n                User = WindowsIdentity.GetCurrent().Name;\n                Logger.LogDebug(\"*** Started as \" + User);\n\n                Logger.Log(Environment.CommandLine);\n\n                bool serviceMode = firstArg == ServiceModeArg;\n\n                // If we're started from the .dll module or from the service process, we should\n                // assume the service mode.\n                if (serviceMode && !runningAsSystem)\n                {\n                    try\n                    {\n                        var sc = new ServiceController(ServiceName);\n                        sc.Start();\n                        return;\n                    }\n                    catch (Exception ex)\n                    {\n                        Logger.Log(\"Couldn't start the service. Will try to continue as not a service.\");\n                        Logger.Log(ex);\n                        ShowServiceModeErrorTooltip = true;\n                        serviceMode = false;\n                        Setting.Values.UseService = false;\n                    }\n                }\n\n                if (serviceMode || runningAsSystem)\n                {\n                    if (args.Length > 2)\n                    {\n                        Helper.UserLocalAppDataPath = args[2].Trim();\n                    }\n                }\n\n                ShutdownWithPowerToys.WaitForPowerToysRunner(etwTrace);\n\n                if (firstArg != string.Empty)\n                {\n                    if (Common.CheckSecondInstance(Common.RunWithNoAdminRight))\n                    {\n                        Logger.Log(\"*** Second instance, exiting...\");\n                        return;\n                    }\n\n                    string myDesktop = Common.GetMyDesktop();\n\n                    if (firstArg.Equals(\"winlogon\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        // Executed by service, running on logon desktop\n                        Logger.Log(\"*** Running on \" + firstArg + \" desktop\");\n                        Common.RunOnLogonDesktop = true;\n                    }\n                    else if (args[1].Trim().Equals(\"default\", StringComparison.OrdinalIgnoreCase))\n                    {\n                        Logger.Log(\"*** Running on \" + firstArg + \" desktop\");\n                    }\n                    else if (args[1].Equals(myDesktop, StringComparison.OrdinalIgnoreCase))\n                    {\n                        Logger.Log(\"*** Running on \" + myDesktop);\n                        if (myDesktop.Equals(\"Screen-saver\", StringComparison.OrdinalIgnoreCase))\n                        {\n                            Common.RunOnScrSaverDesktop = true;\n                            Setting.Values.LastX = Common.JUST_GOT_BACK_FROM_SCREEN_SAVER;\n                        }\n                    }\n                }\n                else\n                {\n                    if (Common.CheckSecondInstance(true))\n                    {\n                        Logger.Log(\"*** Second instance, exiting...\");\n                        return;\n                    }\n                }\n\n                PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersStartedEvent());\n\n                try\n                {\n                    Common.CurrentProcess = Process.GetCurrentProcess();\n                    Common.CurrentProcess.PriorityClass = ProcessPriorityClass.RealTime;\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                }\n\n                Logger.Log(Environment.OSVersion.ToString());\n\n                // Environment.OSVersion is unreliable from 6.2 and up, so just forcefully call the APIs and log the exception unsupported by Windows:\n                int setProcessDpiAwarenessResult = -1;\n\n                try\n                {\n                    setProcessDpiAwarenessResult = NativeMethods.SetProcessDpiAwareness(2);\n                    Logger.Log(string.Format(CultureInfo.InvariantCulture, \"SetProcessDpiAwareness: {0}.\", setProcessDpiAwarenessResult));\n                }\n                catch (DllNotFoundException)\n                {\n                    Logger.Log(\"SetProcessDpiAwareness is unsupported in Windows 7 and lower.\");\n                }\n                catch (EntryPointNotFoundException)\n                {\n                    Logger.Log(\"SetProcessDpiAwareness is unsupported in Windows 7 and lower.\");\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                }\n\n                try\n                {\n                    if (setProcessDpiAwarenessResult != 0)\n                    {\n                        Logger.Log(string.Format(CultureInfo.InvariantCulture, \"SetProcessDPIAware: {0}.\", NativeMethods.SetProcessDPIAware()));\n                    }\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                }\n\n                System.Threading.Thread mainUIThread = Thread.CurrentThread;\n                Common.UIThreadID = mainUIThread.ManagedThreadId;\n                Thread.UpdateThreads(mainUIThread);\n\n                StartInputCallbackThread();\n                if (!Common.RunOnLogonDesktop)\n                {\n                    StartSettingSyncThread();\n                }\n\n                Application.EnableVisualStyles();\n                _ = Application.SetHighDpiMode(HighDpiMode.PerMonitorV2);\n                Application.SetCompatibleTextRenderingDefault(false);\n\n                Common.Init();\n                Common.WndProcCounter++;\n\n                var formScreen = new FrmScreen();\n\n                Application.Run(formScreen);\n\n                etwTrace?.Dispose();\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        private interface ISettingsSyncHelper\n        {\n            [JsonObject(MemberSerialization.OptIn)]\n            public struct MachineSocketState\n            {\n                // Disable false-positive warning due to IPC\n#pragma warning disable CS0649\n                [JsonProperty]\n                public string Name;\n\n                [JsonProperty]\n                public SocketStatus Status;\n#pragma warning restore CS0649\n            }\n\n            void Shutdown();\n\n            void Reconnect();\n\n            void GenerateNewKey();\n\n            void ConnectToMachine(string machineName, string securityKey);\n\n            Task<MachineSocketState[]> RequestMachineSocketStateAsync();\n        }\n\n        private sealed class SettingsSyncHelper : ISettingsSyncHelper\n        {\n            public Task<ISettingsSyncHelper.MachineSocketState[]> RequestMachineSocketStateAsync()\n            {\n                var machineStates = new Dictionary<string, SocketStatus>();\n                if (Common.Sk == null || Common.Sk.TcpSockets == null)\n                {\n                    return Task.FromResult(Array.Empty<ISettingsSyncHelper.MachineSocketState>());\n                }\n\n                foreach (var client in Common.Sk.TcpSockets\n                    .Where(t => t != null && t.IsClient && !string.IsNullOrEmpty(t.MachineName)))\n                {\n                    var exists = machineStates.TryGetValue(client.MachineName, out var existingStatus);\n                    if (!exists || existingStatus == SocketStatus.NA)\n                    {\n                        machineStates[client.MachineName] = client.Status;\n                    }\n                }\n\n                return Task.FromResult(machineStates.Select((state) => new ISettingsSyncHelper.MachineSocketState { Name = state.Key, Status = state.Value }).ToArray());\n            }\n\n            public void ConnectToMachine(string pcName, string securityKey)\n            {\n                Setting.Values.PauseInstantSaving = true;\n\n                Common.ClearComputerMatrix();\n                Setting.Values.MyKey = securityKey;\n                Common.MyKey = securityKey;\n                Common.MagicNumber = Common.Get24BitHash(Common.MyKey);\n                Common.MachineMatrix = new string[Common.MAX_MACHINE] { pcName.Trim().ToUpper(CultureInfo.CurrentCulture), Common.MachineName.Trim(), string.Empty, string.Empty };\n\n                string[] machines = Common.MachineMatrix;\n                Common.MachinePool.Initialize(machines);\n                Common.UpdateMachinePoolStringSetting();\n\n                SocketStuff.InvalidKeyFound = false;\n                Common.ReopenSocketDueToReadError = true;\n                Common.ReopenSockets(true);\n                Common.SendMachineMatrix();\n\n                Setting.Values.PauseInstantSaving = false;\n                Setting.Values.SaveSettings();\n            }\n\n            public void GenerateNewKey()\n            {\n                Setting.Values.PauseInstantSaving = true;\n\n                Setting.Values.EasyMouse = (int)EasyMouseOption.开启;\n                Common.ClearComputerMatrix();\n                Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();\n                Common.GeneratedKey = true;\n\n                Setting.Values.PauseInstantSaving = false;\n                Setting.Values.SaveSettings();\n\n                Reconnect();\n            }\n\n            public void Reconnect()\n            {\n                SocketStuff.InvalidKeyFound = false;\n                Common.ReopenSocketDueToReadError = true;\n                Common.ReopenSockets(true);\n\n                for (int i = 0; i < 10; i++)\n                {\n                    if (Common.AtLeastOneSocketConnected())\n                    {\n                        Common.MMSleep(0.5);\n                        break;\n                    }\n\n                    Common.MMSleep(0.2);\n                }\n\n                Common.SendMachineMatrix();\n            }\n\n            public void Shutdown()\n            {\n                Process[] ps = Process.GetProcessesByName(\"PowerToys.MouseWithoutBorders\");\n                Process me = Process.GetCurrentProcess();\n\n                foreach (Process p in ps)\n                {\n                    if (p.Id != me.Id)\n                    {\n                        p.Kill();\n                    }\n                }\n\n                Common.MainForm.Quit(true, false);\n            }\n        }\n\n        internal static void StartSettingSyncThread()\n        {\n            var serverTaskCancellationSource = new CancellationTokenSource();\n            CancellationToken cancellationToken = serverTaskCancellationSource.Token;\n\n            IpcChannel<SettingsSyncHelper>.StartIpcServer(\"MouseWithoutBorders/SettingsSync\", cancellationToken);\n        }\n\n        internal static void StartInputCallbackThread()\n        {\n            Thread inputCallback = new(new ThreadStart(InputCallbackThread), \"InputCallback Thread\");\n            inputCallback.SetApartmentState(ApartmentState.STA);\n            inputCallback.Priority = ThreadPriority.Highest;\n            inputCallback.Start();\n        }\n\n        private static void InputCallbackThread()\n        {\n            // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n            // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n            using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n            Common.InputCallbackThreadID = Thread.CurrentThread.ManagedThreadId;\n            while (!Common.InitDone)\n            {\n                Thread.Sleep(100);\n            }\n\n            Application.Run(new FrmInputCallback());\n        }\n\n        internal static void StartService()\n        {\n            if (Common.RunWithNoAdminRight)\n            {\n                return;\n            }\n\n            try\n            {\n                // Kill all but me\n                Process me = Process.GetCurrentProcess();\n                Process[] ps = Process.GetProcessesByName(Common.BinaryName);\n                foreach (Process pp in ps)\n                {\n                    if (pp.Id != me.Id)\n                    {\n                        Logger.Log(string.Format(CultureInfo.InvariantCulture, \"Killing process {0}.\", pp.Id));\n                        pp.KillProcess();\n                    }\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n\n            Common.StartMouseWithoutBordersService();\n        }\n\n        internal static string User { get; set; }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Class/SocketStuff.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Net;\nusing System.Net.NetworkInformation;\nusing System.Net.Sockets;\nusing System.Security.Cryptography;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\nusing MouseWithoutBorders.Core;\n\n// <summary>\n//     Socket code.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Exceptions;\n\nusing Thread = MouseWithoutBorders.Core.Thread;\n\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#SendData(System.Byte[])\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#Close()\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#CreateSocket(System.Boolean)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#SendData(System.Byte[],MouseWithoutBorders.IP)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#SendData(System.Object)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#SendFile(System.Net.Sockets.Socket,System.String)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#MainTCPRoutine(System.Net.Sockets.Socket,System.String)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#TCPServerThread(System.Object)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#SendClipboardData(System.Object)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#StartNewTcpClient(MouseWithoutBorders.MachineInf)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#StartNewTcpServer(System.Net.Sockets.Socket,System.String)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#UpdateTCPClients()\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#UpdateTcpSockets(System.Net.Sockets.Socket,MouseWithoutBorders.SocketStatus)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Usage\", \"CA2201:DoNotRaiseReservedExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#.ctor(System.Int32,System.Boolean)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.SocketStuff.#SendData(System.Byte[],MouseWithoutBorders.IP,System.Int32)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1001:TypesThatOwnDisposableFieldsShouldBeDisposable\", Scope = \"type\", Target = \"MouseWithoutBorders.SocketStuff\", Justification = \"Dotnet port with style preservation\")]\n\nnamespace MouseWithoutBorders.Class\n{\n    internal enum SocketStatus : int\n    {\n        NA = 0,\n        Resolving = 1,\n        Connecting = 2,\n        Handshaking = 3,\n        Error = 4,\n        ForceClosed = 5,\n        InvalidKey = 6,\n        Timeout = 7,\n        SendError = 8,\n        Connected = 9,\n    }\n\n    internal class TcpSk : IDisposable\n    {\n        public TcpSk(bool isClient, Socket s, SocketStatus status, string machineName, IPAddress address = null)\n        {\n            IsClient = isClient;\n            BackingSocket = s;\n            Status = status;\n            MachineName = machineName;\n            Address = address;\n            BirthTime = Common.GetTick();\n        }\n\n        public bool IsClient { get; set; }\n\n        public Socket BackingSocket { get; set; }\n\n        public SocketStatus Status { get; set; }\n\n        public string MachineName { get; set; }\n\n        public long BirthTime { get; set; }\n\n        public uint MachineId { get; set; }\n\n        public IPAddress Address { get; set; }\n\n        private Stream encryptedStream;\n        private Stream decryptedStream;\n        private Stream socketStream;\n\n        public Stream EncryptedStream\n        {\n            get\n            {\n                if (encryptedStream == null && BackingSocket.Connected)\n                {\n                    encryptedStream = Common.GetEncryptedStream(new NetworkStream(BackingSocket));\n                    Common.SendOrReceiveARandomDataBlockPerInitialIV(encryptedStream);\n                }\n\n                return encryptedStream;\n            }\n        }\n\n        public Stream DecryptedStream\n        {\n            get\n            {\n                if (decryptedStream == null && BackingSocket.Connected)\n                {\n                    decryptedStream = Common.GetDecryptedStream(new NetworkStream(BackingSocket));\n                    Common.SendOrReceiveARandomDataBlockPerInitialIV(decryptedStream, false);\n                }\n\n                return decryptedStream;\n            }\n        }\n\n        public Stream SocketStream\n        {\n            get\n            {\n                if (socketStream == null && BackingSocket.Connected)\n                {\n                    socketStream = new NetworkStream(BackingSocket);\n                }\n\n                return socketStream;\n            }\n        }\n\n        public void Dispose()\n        {\n            encryptedStream?.Dispose();\n\n            decryptedStream?.Dispose();\n\n            socketStream?.Dispose();\n        }\n    }\n\n    internal class SocketStuff\n    {\n        private readonly int bASE_PORT;\n        private TcpServer skClipboardServer;\n        private TcpServer skMessageServer;\n        internal object TcpSocketsLock = new();\n        internal static bool InvalidKeyFound;\n        internal static bool InvalidKeyFoundOnClientSocket;\n\n        internal const int CONNECT_TIMEOUT = 60000;\n        private static readonly ConcurrentDictionary<string, int> FailedAttempt = new();\n\n        internal List<TcpSk> TcpSockets\n        {\n            get; private set;\n\n            // set { tcpSockets = value; }\n        }\n\n        internal int TcpPort\n        {\n            get;\n\n            // set { tcpPort = value; }\n        }\n\n        private static bool firstRun;\n        private readonly long connectTimeout;\n        private static int restartCount;\n\n        internal SocketStuff(int port, bool byUser)\n        {\n            Logger.LogDebug(\"SocketStuff started.\");\n\n            bASE_PORT = port;\n            Common.Ran = new Random();\n\n            Logger.LogDebug(\"Validating session...\");\n\n            if (Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())\n            {\n                if (Common.DesMachineID != Common.MachineID)\n                {\n                    Common.SwitchToMultipleMode(false, true);\n                }\n\n                if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                {\n                    Common.MainForm.SetTrayIconText(\"Not physical console session.\");\n                    if (byUser)\n                    {\n                        Common.ShowToolTip(\"非物理控制台会话.\", 5000);\n                    }\n                }\n\n                Common.MMSleep(1);\n                Logger.Log(\"Not physical console session.\");\n\n                throw new NotPhysicalConsoleException(\"Not physical console session.\");\n            }\n\n            Logger.LogDebug(\"Creating socket list and mutex...\");\n\n            try\n            {\n                lock (TcpSocketsLock)\n                {\n                    TcpSockets = new List<TcpSk>();\n                }\n\n                bool dummy1 = Setting.Values.MatrixOneRow; // Reading from reg to variable\n                dummy1 = Setting.Values.MatrixCircle;\n\n                if (Setting.Values.IsMyKeyRandom)\n                {\n                    Setting.Values.MyKey = Common.MyKey;\n                }\n\n                Common.MagicNumber = Common.Get24BitHash(Common.MyKey);\n                Common.PackageID = Setting.Values.PackageID;\n\n                TcpPort = bASE_PORT;\n\n                if (Common.SocketMutex == null)\n                {\n                    firstRun = true;\n                    Common.SocketMutex = new Mutex(false, $\"Global\\\\{Application.ProductName}-{FrmAbout.AssemblyVersion}-FF7CDABE-1015-0904-1103-24670FA5D16E\");\n                }\n\n                Common.AcquireSocketMutex();\n            }\n            catch (AbandonedMutexException e)\n            {\n                Logger.TelemetryLogTrace($\"{nameof(SocketStuff)}: {e.Message}\", SeverityLevel.Warning);\n            }\n\n            Common.GetScreenConfig();\n\n            if (firstRun && Common.RunOnScrSaverDesktop)\n            {\n                firstRun = false;\n            }\n\n            // JUST_GOT_BACK_FROM_SCREEN_SAVER: For bug: monitor does not turn off after logon screen saver exits\n            else if (!Common.RunOnScrSaverDesktop)\n            {\n                if (Setting.Values.LastX == Common.JUST_GOT_BACK_FROM_SCREEN_SAVER)\n                {\n                    Common.NewDesMachineID = Common.DesMachineID = Common.MachineID;\n                }\n                else\n                {\n                    // Common.Log(\"Getting IP: \" + Setting.Values.DesMachineID.ToString(CultureInfo.CurrentCulture));\n                    Common.LastX = Setting.Values.LastX;\n                    Common.LastY = Setting.Values.LastY;\n\n                    if (Common.RunOnLogonDesktop && Setting.Values.DesMachineID == (uint)ID.ALL)\n                    {\n                        Common.SwitchToMultipleMode(true, false);\n                    }\n                    else\n                    {\n                        Common.SwitchToMultipleMode(false, false);\n                    }\n                }\n            }\n\n            connectTimeout = Common.GetTick() + (CONNECT_TIMEOUT / 2);\n            Exception openSocketErr;\n\n            /*\n             * The machine might be getting a new IP address from its DHCP server\n             * for ex, when a laptop with a wireless connection just wakes up, might take long time:(\n             * */\n\n            Common.GetMachineName(); // IPs might have been changed\n            Common.UpdateMachineTimeAndID();\n\n            Logger.LogDebug(\"Creating sockets...\");\n\n            openSocketErr = CreateSocket();\n\n            int sleepSecs = 0, errCode = 0;\n\n            if (openSocketErr != null)\n            {\n                if (openSocketErr is SocketException)\n                {\n                    errCode = (openSocketErr as SocketException).ErrorCode;\n\n                    switch (errCode)\n                    {\n                        case 0: // No error.\n                            break;\n\n                        case 10048: // WSAEADDRINUSE\n                            sleepSecs = 10;\n\n                            // It is reasonable to give a try on restarting MwB processes in other sessions.\n                            if (restartCount++ < 5 && Common.IsMyDesktopActive() && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                            {\n                                Logger.TelemetryLogTrace(\"Restarting the service dues to WSAEADDRINUSE.\", SeverityLevel.Warning);\n                                Program.StartService();\n                                Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;\n                            }\n\n                            break;\n\n                        case 10049: // WSAEADDRNOTAVAIL\n                            sleepSecs = 1;\n                            break;\n\n                        default:\n                            sleepSecs = 5;\n                            break;\n                    }\n                }\n                else\n                {\n                    sleepSecs = 10;\n                }\n\n                if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                {\n                    if (byUser)\n                    {\n                        Common.ShowToolTip(errCode.ToString(CultureInfo.CurrentCulture) + \": \" + openSocketErr.Message, 5000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n                    }\n                }\n\n                Common.MMSleep(sleepSecs);\n                Common.ReleaseSocketMutex();\n                throw new ExpectedSocketException(openSocketErr.Message);\n            }\n            else\n            {\n                restartCount = 0;\n\n                if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                {\n                    IpcHelper.CreateIpcServer(false);\n                }\n\n                Common.MainForm.UpdateNotifyIcon();\n            }\n        }\n\n        internal void Close(bool sentWait)\n        {\n            try\n            {\n                if (!Common.RunOnScrSaverDesktop)\n                {\n                    Setting.Values.LastX = Common.LastX;\n                    Setting.Values.LastY = Common.LastY;\n                    Setting.Values.PackageID = Common.PackageID;\n\n                    // Common.Log(\"Saving IP: \" + Setting.Values.DesMachineID.ToString(CultureInfo.CurrentCulture));\n                    Setting.Values.DesMachineID = (uint)Common.DesMachineID;\n                }\n\n                _ = Common.ExecuteAndTrace(\n                    \"Closing sockets\",\n                    () =>\n                    {\n                        Logger.LogDebug($\"Closing socket [{skMessageServer?.Name}].\");\n                        skMessageServer?.Close(); // The original ones, not the socket instances produced by the accept() method.\n                        skMessageServer = null;\n\n                        Logger.LogDebug($\"Closing socket [{skClipboardServer?.Name}].\");\n                        skClipboardServer?.Close();\n                        skClipboardServer = null;\n                        try\n                        {\n                            // If these sockets are failed to be closed then the tool would not function properly, more logs are added for debugging.\n                            lock (TcpSocketsLock)\n                            {\n                                int c = 0;\n\n                                if (TcpSockets != null)\n                                {\n                                    Logger.LogDebug(\"********** Closing Sockets: \" + TcpSockets.Count.ToString(CultureInfo.InvariantCulture));\n\n                                    List<TcpSk> notClosedSockets = new();\n\n                                    foreach (TcpSk t in TcpSockets)\n                                    {\n                                        if (t != null && t.BackingSocket != null && t.Status != SocketStatus.Resolving)\n                                        {\n                                            try\n                                            {\n                                                t.MachineName = \"$*NotUsed*$\";\n                                                t.Status = t.Status >= 0 ? 0 : t.Status - 1;\n\n                                                if (sentWait)\n                                                {\n                                                    t.BackingSocket.Close(1);\n                                                }\n                                                else\n                                                {\n                                                    t.BackingSocket.Close();\n                                                }\n\n                                                c++;\n\n                                                continue;\n                                            }\n                                            catch (SocketException e)\n                                            {\n                                                string log = $\"Socket.Close error: {e.GetType()}/{e.Message}. This is expected when the socket is already closed by remote host.\";\n                                                Logger.Log(log);\n                                            }\n                                            catch (ObjectDisposedException e)\n                                            {\n                                                string log = $\"Socket.Close error: {e.GetType()}/{e.Message}. This is expected when the socket is already disposed.\";\n                                                Logger.Log(log);\n                                            }\n                                            catch (Exception e)\n                                            {\n                                                Logger.Log(e);\n                                            }\n\n                                            // If there was an error closing the socket:\n                                            if ((int)t.Status > -5)\n                                            {\n                                                notClosedSockets.Add(t); // Try to give a few times to close the socket later on.\n                                            }\n                                        }\n                                    }\n\n                                    TcpSockets = notClosedSockets;\n                                }\n\n                                Logger.LogDebug(\"********** Sockets Closed: \" + c.ToString(CultureInfo.CurrentCulture));\n                            }\n                        }\n                        catch (Exception e)\n                        {\n                            Logger.Log(e);\n                        }\n                    },\n                    TimeSpan.FromSeconds(3),\n                    true);\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n            finally\n            {\n                Common.ReleaseSocketMutex();\n            }\n\n            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n            {\n                try\n                {\n                    IpcHelper.CreateIpcServer(true);\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                }\n            }\n        }\n\n        private Exception CreateSocket()\n        {\n            try\n            {\n                skMessageServer = new TcpServer(TcpPort + 1, new ParameterizedThreadStart(TCPServerThread));\n                skClipboardServer = new TcpServer(TcpPort, new ParameterizedThreadStart(AcceptConnectionAndSendClipboardData));\n            }\n            catch (SocketException e)\n            {\n                Logger.Log(e);\n                return e;\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n                return e;\n            }\n\n            Logger.LogDebug(\"==================================================\");\n            return null;\n        }\n\n        private static int TcpSendData(TcpSk tcp, byte[] bytes)\n        {\n            Stream encryptedStream = tcp.EncryptedStream;\n\n            if (tcp.BackingSocket == null || !tcp.BackingSocket.Connected || encryptedStream == null)\n            {\n                string log = $\"{nameof(TcpSendData)}: The socket is no longer connected, it could have been closed by the remote host.\";\n                Logger.Log(log);\n                throw new ExpectedSocketException(log);\n            }\n\n            bytes[3] = (byte)((Common.MagicNumber >> 24) & 0xFF);\n            bytes[2] = (byte)((Common.MagicNumber >> 16) & 0xFF);\n            bytes[1] = 0;\n            for (int i = 2; i < Common.PACKAGE_SIZE; i++)\n            {\n                bytes[1] = (byte)(bytes[1] + bytes[i]);\n            }\n\n            try\n            {\n                encryptedStream.Write(bytes, 0, bytes.Length);\n            }\n            catch (IOException e)\n            {\n                string log = $\"{nameof(TcpSendData)}: Exception writing to the socket: {tcp.MachineName}: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                Logger.Log(log);\n\n                throw e.InnerException is SocketException se ? new ExpectedSocketException(se) : new ExpectedSocketException(log);\n            }\n\n            return bytes.Length;\n        }\n\n        private static void ProcessReceivedDataEx(byte[] buf)\n        {\n            int magic;\n            byte checksum = 0;\n\n            magic = (buf[3] << 24) + (buf[2] << 16);\n\n            if (magic != (Common.MagicNumber & 0xFFFF0000))\n            {\n                Logger.Log(\"Magic number invalid!\");\n                buf[0] = (byte)PackageType.Invalid;\n            }\n\n            for (int i = 2; i < Common.PACKAGE_SIZE; i++)\n            {\n                checksum = (byte)(checksum + buf[i]);\n            }\n\n            if (buf[1] != checksum)\n            {\n                Logger.Log(\"Checksum invalid!\");\n                buf[0] = (byte)PackageType.Invalid;\n            }\n\n            buf[3] = buf[2] = buf[1] = 0;\n        }\n\n        internal static DATA TcpReceiveData(TcpSk tcp, out int bytesReceived)\n        {\n            byte[] buf = new byte[Common.PACKAGE_SIZE_EX];\n            Stream decryptedStream = tcp.DecryptedStream;\n\n            if (tcp.BackingSocket == null || !tcp.BackingSocket.Connected || decryptedStream == null)\n            {\n                string log = $\"{nameof(TcpReceiveData)}: The socket is no longer connected, it could have been closed by the remote host.\";\n                Logger.Log(log);\n                throw new ExpectedSocketException(log);\n            }\n\n            DATA package;\n\n            try\n            {\n                bytesReceived = decryptedStream.ReadEx(buf, 0, Common.PACKAGE_SIZE);\n\n                if (bytesReceived != Common.PACKAGE_SIZE)\n                {\n                    buf[0] = bytesReceived == 0 ? (byte)PackageType.Error : (byte)PackageType.Invalid;\n                }\n                else\n                {\n                    ProcessReceivedDataEx(buf);\n                }\n\n                package = new DATA(buf);\n\n                if (package.IsBigPackage)\n                {\n                    bytesReceived = decryptedStream.ReadEx(buf, Common.PACKAGE_SIZE, Common.PACKAGE_SIZE);\n\n                    if (bytesReceived != Common.PACKAGE_SIZE)\n                    {\n                        buf[0] = bytesReceived == 0 ? (byte)PackageType.Error : (byte)PackageType.Invalid;\n                    }\n                    else\n                    {\n                        package.Bytes = buf;\n                    }\n                }\n            }\n            catch (IOException e)\n            {\n                string log = $\"{nameof(TcpReceiveData)}: Exception reading from the socket: {tcp.MachineName}: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                Logger.Log(log);\n\n                throw e.InnerException is SocketException se ? new ExpectedSocketException(se) : new ExpectedSocketException(log);\n            }\n\n            return package;\n        }\n\n        private static void PreProcessData(PackageType type)\n        {\n            switch (type)\n            {\n                case PackageType.Keyboard:\n                    Common.PackageSent.Keyboard++;\n                    break;\n\n                case PackageType.Mouse:\n                    Common.PackageSent.Mouse++;\n                    break;\n\n                case PackageType.Heartbeat:\n                case PackageType.Heartbeat_ex:\n                    Common.PackageSent.Heartbeat++;\n                    break;\n\n                case PackageType.Hello:\n                    Common.PackageSent.Hello++;\n                    break;\n\n                case PackageType.ByeBye:\n                    Common.PackageSent.ByeBye++;\n                    break;\n\n                case PackageType.Matrix:\n                    Common.PackageSent.Matrix++;\n                    break;\n\n                default:\n                    byte subtype = (byte)((uint)type & 0x000000FF);\n                    switch (subtype)\n                    {\n                        case (byte)PackageType.ClipboardText:\n                            Common.PackageSent.ClipboardText++;\n                            break;\n\n                        case (byte)PackageType.ClipboardImage:\n                            Common.PackageSent.ClipboardImage++;\n                            break;\n\n                        default:\n                            // Common.Log(\"Send: Other type (1-17)\");\n                            break;\n                    }\n\n                    break;\n            }\n        }\n\n        internal int TcpSend(TcpSk tcp, DATA data)\n        {\n            PreProcessData(data.Type);\n\n            if (data.Src == ID.NONE)\n            {\n                data.Src = Common.MachineID;\n            }\n\n            byte[] dataAsBytes = data.Bytes;\n            int rv = TcpSendData(tcp, dataAsBytes);\n            if (rv < dataAsBytes.Length)\n            {\n                Logger.Log(\"TcpSend error! Length of sent data is unexpected.\");\n                UpdateTcpSockets(tcp, SocketStatus.SendError);\n                throw new SocketException((int)SocketStatus.SendError);\n            }\n\n            return rv;\n        }\n\n        private void TCPServerThread(object param)\n        {\n            // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n            // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n            using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n            try\n            {\n                TcpListener server = param as TcpListener;\n                do\n                {\n                    Logger.LogDebug(\"TCPServerThread: Waiting for request...\");\n                    Socket s = server.AcceptSocket();\n\n                    _ = Task.Run(() =>\n                    {\n                        try\n                        {\n                            AddSocket(s);\n                        }\n                        catch (Exception e)\n                        {\n                            Logger.Log(e);\n                        }\n                    });\n                }\n                while (true);\n            }\n            catch (InvalidOperationException e)\n            {\n                string log = $\"TCPServerThread.AcceptSocket: The server socket could have been closed. {e.Message}\";\n                Logger.Log(log);\n            }\n            catch (SocketException e)\n            {\n                if (e.ErrorCode == (int)SocketError.Interrupted)\n                {\n                    Logger.Log(\"TCPServerThread.AcceptSocket: A blocking socket call was canceled.\");\n                }\n                else\n                {\n                    Logger.Log(e);\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        private static string GetMachineNameFromSocket(Socket socket)\n        {\n            string stringIP = socket.RemoteEndPoint.ToString();\n            string name = null;\n\n            try\n            {\n                // Remote machine has IP changed, update it.\n                name = Dns.GetHostEntry((socket.RemoteEndPoint as IPEndPoint).Address).HostName;\n            }\n            catch (SocketException e)\n            {\n                Logger.Log($\"{nameof(GetMachineNameFromSocket)}: {e.Message}\");\n                return stringIP;\n            }\n\n            // Remove the domain part.\n            if (!string.IsNullOrEmpty(name))\n            {\n                int dotPos = name.IndexOf('.');\n\n                if (dotPos > 0)\n                {\n                    Logger.LogDebug(\"Removing domain part from the full machine name: {0}.\", name);\n                    name = name[..dotPos];\n                }\n            }\n\n            return string.IsNullOrEmpty(name) ? stringIP : name;\n        }\n\n        private void AddSocket(Socket s)\n        {\n            string machineName = GetMachineNameFromSocket(s);\n            Logger.Log($\"New connection from client: [{machineName}].\");\n            TcpSk tcp = AddTcpSocket(false, s, SocketStatus.Connecting, machineName);\n            StartNewTcpServer(tcp, machineName);\n        }\n\n        private void StartNewTcpServer(TcpSk tcp, string machineName)\n        {\n            void ServerThread()\n            {\n                // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n                // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n                using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n                try\n                {\n                    // Receiving packages\n                    MainTCPRoutine(tcp, machineName, false);\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                }\n            }\n\n            Thread t = new(ServerThread, \"TCP Server Thread \" + tcp.BackingSocket.LocalEndPoint.ToString() + \" : \" + machineName);\n\n            t.SetApartmentState(ApartmentState.STA);\n            t.Start();\n        }\n\n        internal void UpdateTCPClients()\n        {\n            if (InvalidKeyFound)\n            {\n                return;\n            }\n\n            Logger.LogDebug(\"!!!!! UpdateTCPClients !!!!!\");\n\n            try\n            {\n                if (Common.MachineMatrix != null)\n                {\n                    Logger.LogDebug(\"MachineMatrix = \" + string.Join(\", \", Common.MachineMatrix));\n\n                    foreach (string st in Common.MachineMatrix)\n                    {\n                        string machineName = st.Trim();\n                        if (!string.IsNullOrEmpty(machineName) &&\n                            !machineName.Equals(Common.MachineName.Trim(), StringComparison.OrdinalIgnoreCase))\n                        {\n                            bool found = false;\n\n                            found = Common.IsConnectedByAClientSocketTo(machineName);\n\n                            if (found)\n                            {\n                                Logger.LogDebug(machineName + \" is already connected! ^^^^^^^^^^^^^^^^^^^^^\");\n                                continue;\n                            }\n\n                            StartNewTcpClient(machineName);\n                        }\n                    }\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        private static readonly Dictionary<string, List<IPAddress>> BadIPs = new();\n        private static readonly Lock BadIPsLock = new();\n\n        private static bool IsBadIP(string machineName, IPAddress ip)\n        {\n            lock (BadIPsLock)\n            {\n                return BadIPs.ContainsKey(machineName) && BadIPs.TryGetValue(machineName, out List<IPAddress> ips) && ips.Contains(ip);\n            }\n        }\n\n        private static void AddBadIP(string machineName, IPAddress ip)\n        {\n            if (!IsBadIP(machineName, ip))\n            {\n                lock (BadIPsLock)\n                {\n                    List<IPAddress> ips;\n\n                    if (BadIPs.ContainsKey(machineName))\n                    {\n                        _ = BadIPs.TryGetValue(machineName, out ips);\n                    }\n                    else\n                    {\n                        ips = new List<IPAddress>();\n                        BadIPs.Add(machineName, ips);\n                    }\n\n                    ips.Add(ip);\n                }\n            }\n        }\n\n        internal static void ClearBadIPs()\n        {\n            lock (BadIPsLock)\n            {\n                if (BadIPs.Count > 0)\n                {\n                    BadIPs.Clear();\n                }\n            }\n        }\n\n        internal void StartNewTcpClient(string machineName)\n        {\n            void ClientThread(object obj)\n            {\n                // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n                // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n                using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n                IPHostEntry host;\n                bool useName2IP = false;\n                List<IPAddress> validAddresses = new();\n                List<IPAddress> validatedAddresses = new();\n                string validAddressesSt = string.Empty;\n\n                // Add a dummy socket to show the status.\n                Socket dummySocket = new(AddressFamily.Unspecified, SocketType.Stream, ProtocolType.Tcp);\n                TcpSk dummyTcp = AddTcpSocket(true, dummySocket, SocketStatus.Resolving, machineName);\n\n                Logger.LogDebug(\"Connecting to: \" + machineName);\n\n                if (!string.IsNullOrEmpty(Setting.Values.Name2IP))\n                {\n                    string combinedName2ipList = Setting.Values.Name2IpPolicyList + Separator + Setting.Values.Name2IP;\n                    string[] name2ip = combinedName2ipList.Split(Separator, StringSplitOptions.RemoveEmptyEntries);\n                    string[] nameNip;\n\n                    if (name2ip != null)\n                    {\n                        foreach (string st in name2ip)\n                        {\n                            nameNip = st.Split(BlankSeparator, StringSplitOptions.RemoveEmptyEntries);\n\n                            if (nameNip != null && nameNip.Length >= 2 && nameNip[0].Trim().Equals(machineName, StringComparison.OrdinalIgnoreCase)\n                                && IPAddress.TryParse(nameNip[1].Trim(), out IPAddress ip) && !validAddressesSt.Contains(\"[\" + ip.ToString() + \"]\")\n                                )\n                            {\n                                validatedAddresses.Add(ip);\n                                validAddressesSt += \"[\" + ip.ToString() + \"]\";\n                            }\n                        }\n                    }\n\n                    if (validatedAddresses.Count > 0)\n                    {\n                        useName2IP = true;\n\n                        Logger.LogDebug(\"Using both user-defined Name-to-IP mappings and DNS result for \" + machineName);\n\n                        Common.ShowToolTip(\"为 \" + machineName + \" 同时使用用户自定义 IP 映射和 DNS 结果\", 3000, ToolTipIcon.Info, false);\n\n                        if (!CheckForSameSubNet(validatedAddresses, machineName))\n                        {\n                            return;\n                        }\n\n                        foreach (IPAddress vip in validatedAddresses)\n                        {\n                            StartNewTcpClientThread(machineName, vip);\n                        }\n\n                        validatedAddresses.Clear();\n                    }\n                }\n\n                try\n                {\n                    host = Dns.GetHostEntry(machineName);\n                }\n                catch (SocketException e)\n                {\n                    host = null;\n\n                    UpdateTcpSockets(dummyTcp, SocketStatus.Timeout);\n\n                    Common.ShowToolTip(e.Message + \": \" + machineName, 10000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n\n                    Logger.Log($\"{nameof(StartNewTcpClient)}.{nameof(Dns.GetHostEntry)}: {e.Message}\");\n                }\n\n                UpdateTcpSockets(dummyTcp, SocketStatus.NA);\n\n                if (!Common.InMachineMatrix(machineName))\n                {\n                    // While Resolving from name to IP, user may have changed the machine name and clicked on Apply.\n                    return;\n                }\n\n                if (host != null)\n                {\n                    string ipLog = string.Empty;\n\n                    foreach (IPAddress ip in host.AddressList)\n                    {\n                        ipLog += \"<\" + ip.ToString() + \">\";\n\n                        if ((ip.AddressFamily == AddressFamily.InterNetwork || ip.AddressFamily == AddressFamily.InterNetworkV6) && !validAddressesSt.Contains(\"[\" + ip.ToString() + \"]\"))\n                        {\n                            validAddresses.Add(ip);\n                            validAddressesSt += \"[\" + ip.ToString() + \"]\";\n                        }\n                    }\n\n                    Logger.LogDebug(machineName + ipLog);\n                }\n\n                if (validAddresses.Count > 0)\n                {\n                    if (!Setting.Values.ReverseLookup)\n                    {\n                        validatedAddresses = validAddresses;\n                        ClearBadIPs();\n                    }\n                    else\n                    {\n                        foreach (IPAddress ip in validAddresses)\n                        {\n                            if (IsBadIP(machineName, ip))\n                            {\n                                Logger.Log($\"Skip bad IP address: {ip}\");\n                                continue;\n                            }\n\n                            try\n                            {\n                                // Reverse lookup to validate the IP Address.\n                                string hn = Dns.GetHostEntry(ip).HostName;\n\n                                if (hn.StartsWith(machineName, StringComparison.CurrentCultureIgnoreCase) || hn.Equals(ip.ToString(), StringComparison.OrdinalIgnoreCase))\n                                {\n                                    validatedAddresses.Add(ip);\n                                }\n                                else\n                                {\n                                    Logger.Log($\"DNS information of machine not matched: {machineName} => {ip} => {hn}.\");\n                                    AddBadIP(machineName, ip);\n                                }\n                            }\n                            catch (SocketException se)\n                            {\n                                Logger.Log($\"{nameof(StartNewTcpClient)}: DNS information of machine not matched: {machineName} => {ip} => {se.Message}.\");\n                                AddBadIP(machineName, ip);\n                            }\n                            catch (ArgumentException ae)\n                            {\n                                Logger.Log($\"{nameof(StartNewTcpClient)}: DNS information of machine not matched: {machineName} => {ip} => {ae.Message}.\");\n                                AddBadIP(machineName, ip);\n                            }\n                        }\n                    }\n                }\n\n                if (validatedAddresses.Count > 0)\n                {\n                    if (!CheckForSameSubNet(validatedAddresses, machineName))\n                    {\n                        return;\n                    }\n\n                    foreach (IPAddress ip in validatedAddresses)\n                    {\n                        StartNewTcpClientThread(machineName, ip);\n                    }\n                }\n                else\n                {\n                    Logger.Log(\"Cannot resolve IPv4 Addresses of machine: \" + machineName);\n\n                    if (!useName2IP)\n                    {\n                        Common.ShowToolTip($\"无法解析对方电脑的 IP 地址: {machineName}.\\r\\n请解决 DNS 问题，或者手动设置 IP 地址映射.\", 10000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n                    }\n                }\n            }\n\n            Thread t = new(\n                ClientThread, \"StartNewTcpClient.\" + machineName);\n\n            t.SetApartmentState(ApartmentState.STA);\n            t.Start();\n        }\n\n        private bool CheckForSameSubNet(List<IPAddress> validatedAddresses, string machineName)\n        {\n            if (!Setting.Values.SameSubNetOnly)\n            {\n                return true;\n            }\n\n            // Only support if IPv4 addresses found in both.\n            IEnumerable<IPAddress> remoteIPv4Addresses = validatedAddresses.Where(addr => addr?.AddressFamily == AddressFamily.InterNetwork);\n\n            if (!remoteIPv4Addresses.Any())\n            {\n                Logger.Log($\"No IPv4 resolved from the remote machine: {machineName}.\");\n                return true;\n            }\n\n            List<IPAddress> localIPv4Addresses = GetMyIPv4Addresses().ToList();\n\n            if (localIPv4Addresses.Count == 0)\n            {\n                Logger.Log($\"No IPv4 resolved from the local machine: {Common.MachineName}\");\n                return true;\n            }\n\n            foreach (IPAddress remote in remoteIPv4Addresses)\n            {\n                foreach (IPAddress local in localIPv4Addresses)\n                {\n                    byte[] myIPAddressBytes = local.GetAddressBytes();\n                    byte[] yourIPAddressBytes = remote.GetAddressBytes();\n\n                    // Same WAN?\n                    if (myIPAddressBytes[0] == yourIPAddressBytes[0] && myIPAddressBytes[1] == yourIPAddressBytes[1])\n                    {\n                        return true;\n                    }\n                }\n            }\n\n            Logger.Log($\"Skip machine not in the same network: {machineName}.\");\n\n            return false;\n        }\n\n        private IEnumerable<IPAddress> GetMyIPv4Addresses()\n        {\n            try\n            {\n                IEnumerable<IPAddress> ip4addresses = NetworkInterface.GetAllNetworkInterfaces()?\n                    .Where(networkInterface =>\n                        (networkInterface.NetworkInterfaceType == NetworkInterfaceType.Ethernet || networkInterface.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)\n                        && networkInterface.OperationalStatus == OperationalStatus.Up)\n                        .SelectMany(ni => ni?.GetIPProperties()?.UnicastAddresses.Select(uni => uni?.Address))\n                        .Where(addr => addr?.AddressFamily == AddressFamily.InterNetwork);\n\n                return ip4addresses;\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n                return Enumerable.Empty<IPAddress>();\n            }\n        }\n\n        private void StartNewTcpClientThread(string machineName, IPAddress ip)\n        {\n            void NewTcpClient()\n            {\n                // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n                // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n                using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n                TcpClient tcpClient = null;\n\n                try\n                {\n                    tcpClient = new TcpClient(AddressFamily.InterNetworkV6);\n                    tcpClient.Client.DualMode = true;\n\n                    if (Common.IsConnectedByAClientSocketTo(machineName))\n                    {\n                        Logger.LogDebug(machineName + \" is already connected by another client socket.\");\n                        return;\n                    }\n\n                    if (Common.IsConnectingByAClientSocketTo(machineName, ip))\n                    {\n                        Logger.LogDebug($\"{machineName}:{ip} is already being connected by another client socket.\");\n                        return;\n                    }\n\n                    TcpSk tcp = AddTcpSocket(true, tcpClient.Client, SocketStatus.Connecting, machineName, ip);\n\n                    // Update the other server socket's machine name based on this corresponding client socket.\n                    UpdateTcpSockets(tcp, SocketStatus.Connecting);\n\n                    Logger.LogDebug(string.Format(CultureInfo.CurrentCulture, \"=====> Connecting to: {0}:{1}\", machineName, ip.ToString()));\n\n                    long timeoutLeft;\n\n                    do\n                    {\n                        try\n                        {\n                            tcpClient.Connect(ip, TcpPort + 1);\n                        }\n                        catch (ObjectDisposedException)\n                        {\n                            // When user reconnects.\n                            Logger.LogDebug($\"tcpClient.Connect: The socket has already been disposed: {machineName}:{ip}\");\n                            return;\n                        }\n                        catch (SocketException e)\n                        {\n                            timeoutLeft = connectTimeout - Common.GetTick();\n\n                            if (timeoutLeft > 0)\n                            {\n                                Logger.LogDebug($\"tcpClient.Connect: {timeoutLeft}: {e.Message}\");\n                                Thread.Sleep(1000);\n                                continue;\n                            }\n                            else\n                            {\n                                Logger.Log($\"tcpClient.Connect: Unable to connect after a timeout: {machineName}:{ip} : {e.Message}\");\n\n                                string message = $\"连接超时: {machineName}:{ip}\";\n\n                                Common.ShowToolTip(message, 5000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n\n                                UpdateTcpSockets(tcp, SocketStatus.Timeout);\n                                return;\n                            }\n                        }\n\n                        break;\n                    }\n                    while (true);\n\n                    Logger.LogDebug($\"=====> Connected: {tcpClient.Client.LocalEndPoint} => {machineName}: {ip}\");\n\n                    // Sending/Receiving packages\n                    MainTCPRoutine(tcp, machineName, true);\n                }\n                catch (ObjectDisposedException e)\n                {\n                    Logger.Log($\"{nameof(StartNewTcpClientThread)}: The socket could have been closed/disposed due to machine switch: {e.Message}\");\n                }\n                catch (SocketException e)\n                {\n                    // DHCP error, etc.\n                    string localIP = tcpClient?.Client?.LocalEndPoint?.ToString();\n\n                    if (localIP != null && (localIP.StartsWith(\"169.254\", StringComparison.InvariantCulture) || localIP.ToString().StartsWith(\"0.0\", StringComparison.InvariantCulture)))\n                    {\n                        Common.ShowToolTip($\"错误: 该机器对于 [{localIP}] 的连接性有限.\", 5000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n                    }\n                    else\n                    {\n                        Logger.TelemetryLogTrace($\"{nameof(StartNewTcpClientThread)}: Error: {e.Message} on the IP Address: {localIP}\", SeverityLevel.Error);\n                    }\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                }\n            }\n\n            Thread t = new(NewTcpClient, \"TCP Client Thread \" + machineName + \" \" + ip.ToString());\n\n            t.SetApartmentState(ApartmentState.STA);\n            t.Start();\n        }\n\n        private void FlagReopenSocketIfNeeded(Exception e)\n        {\n            /* SCENARIO: MachineA has MM blocked by firewall but MachineA can connect to MachineB so the tool would work normally (MM is not blocked by firewall in MachineB).\n            * 1. a connection from A to B is working. Mouse/Keyboard is connected to A.\n            * 2. User moves Mouse to B and lock B by Ctrl+Alt+L.\n            * 3. B closes all sockets before switches to logon desktop. The client socket in A gets reset by B (the only connection between A and B).\n            * 4. B is now on the logon desktop and tries to connect to A, connection fails since it is block by firewall in A.\n            * 5. When the client socket gets reset in A, it should retry to connect to B => this is the fix implemented by few lines of code below.\n            * */\n\n            // WSAECONNRESET\n            if (e is ExpectedSocketException se && se.ShouldReconnect)\n            {\n                Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;\n                Logger.Log($\"MainTCPRoutine: {nameof(FlagReopenSocketIfNeeded)}\");\n            }\n        }\n\n        private long lastRemoteMachineID;\n        internal static readonly string[] Separator = new string[] { \"\\r\\n\" };\n        internal static readonly char[] BlankSeparator = new char[] { ' ' };\n\n        private void MainTCPRoutine(TcpSk tcp, string machineName, bool isClient)\n        {\n            int packageCount = 0;\n            DATA d;\n            string remoteMachine = string.Empty;\n            string strIP = string.Empty;\n            ID remoteID = ID.NONE;\n\n            byte[] buf = RandomNumberGenerator.GetBytes(Common.PACKAGE_SIZE_EX);\n            d = new DATA(buf);\n\n            TcpSk currentTcp = tcp;\n            Socket currentSocket = currentTcp.BackingSocket;\n\n            if (currentSocket == null)\n            {\n                Logger.LogDebug($\"{nameof(MainTCPRoutine)}: The socket could have been closed/disposed by other threads.\");\n                return;\n            }\n\n            try\n            {\n                currentSocket.SendBufferSize = Common.PACKAGE_SIZE * 10000;\n                currentSocket.ReceiveBufferSize = Common.PACKAGE_SIZE * 10000;\n                currentSocket.NoDelay = true; // This is very interesting to know:(\n                currentSocket.SendTimeout = 500;\n                d.MachineName = Common.MachineName;\n\n                d.Type = PackageType.Handshake;\n\n                for (int i = 0; i < 10; i++)\n                {\n                    _ = TcpSend(currentTcp, d);\n                }\n\n                d.Machine1 = ~d.Machine1;\n                d.Machine2 = ~d.Machine2;\n                d.Machine3 = ~d.Machine3;\n                d.Machine4 = ~d.Machine4;\n\n                UpdateTcpSockets(currentTcp, SocketStatus.Handshaking);\n\n                strIP = Common.GetRemoteStringIP(currentSocket, true);\n                remoteMachine = string.IsNullOrEmpty(machineName) ? GetMachineNameFromSocket(currentSocket) : machineName;\n\n                Logger.LogDebug($\"MainTCPRoutine: Remote machineName/IP = {remoteMachine}/{strIP}\");\n            }\n            catch (ObjectDisposedException e)\n            {\n                Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;\n                UpdateTcpSockets(currentTcp, SocketStatus.ForceClosed);\n                currentSocket.Close();\n                Logger.Log($\"{nameof(MainTCPRoutine)}: The socket could have been closed/disposed by other threads: {e.Message}\");\n            }\n            catch (Exception e)\n            {\n                UpdateTcpSockets(currentTcp, SocketStatus.ForceClosed);\n                FlagReopenSocketIfNeeded(e);\n                currentSocket.Close();\n                Logger.Log(e);\n            }\n\n            int errCount = 0;\n\n            while (true)\n            {\n                try\n                {\n                    DATA package = TcpReceiveData(currentTcp, out int receivedCount);\n                    remoteID = package.Src;\n\n                    if (package.Type == PackageType.Error)\n                    {\n                        errCount++;\n\n                        string log = $\"{nameof(MainTCPRoutine)}.TcpReceive error, invalid package from {remoteMachine}: {receivedCount}\";\n                        Logger.Log(log);\n\n                        if (receivedCount > 0)\n                        {\n                            Common.ShowToolTip($\"来自 {remoteMachine} 的数据包无效. 请确保连接密码一致.\", 5000, ToolTipIcon.Warning, false);\n                        }\n\n                        if (errCount > 5)\n                        {\n                            Common.MMSleep(1);\n\n                            UpdateTcpSockets(currentTcp, SocketStatus.Error);\n                            currentSocket.Close();\n\n                            /*\n                             * Sometimes when the peer machine closes the connection, we do not actually get an exception.\n                             * Socket status is still connected and a read on the socket stream returns 0 byte.\n                             * In this case, we should give ONE try to reconnect.\n                             */\n\n                            if (Common.ReopenSocketDueToReadError)\n                            {\n                                Common.PleaseReopenSocket = Common.REOPEN_WHEN_WSAECONNRESET;\n                                Common.ReopenSocketDueToReadError = false;\n                            }\n\n                            break;\n                        }\n                    }\n                    else\n                    {\n                        errCount = 0;\n                    }\n\n                    if (package.Type == PackageType.Handshake)\n                    {\n                        // Common.Log(\"Got a Handshake signal!\");\n                        package.Type = PackageType.HandshakeAck;\n                        package.Src = ID.NONE;\n                        package.MachineName = Common.MachineName;\n\n                        package.Machine1 = ~package.Machine1;\n                        package.Machine2 = ~package.Machine2;\n                        package.Machine3 = ~package.Machine3;\n                        package.Machine4 = ~package.Machine4;\n\n                        _ = TcpSend(currentTcp, package);\n                    }\n                    else\n                    {\n                        if (packageCount >= 0)\n                        {\n                            if (++packageCount >= 10)\n                            {\n                                // Common.ShowToolTip(\"Invalid Security Key from \" + remoteMachine, 5000);\n                                Logger.Log(\"More than 10 invalid packages received!\");\n\n                                package.Type = PackageType.Invalid;\n\n                                for (int i = 0; i < 10; i++)\n                                {\n                                    _ = TcpSend(currentTcp, package);\n                                }\n\n                                Common.MMSleep(2);\n\n                                UpdateTcpSockets(currentTcp, SocketStatus.InvalidKey);\n                                currentSocket.Close();\n                                break;\n                            }\n                            else if (package.Type == PackageType.HandshakeAck)\n                            {\n                                if (package.Machine1 == d.Machine1 && package.Machine2 == d.Machine2 &&\n                                   package.Machine3 == d.Machine3 && package.Machine4 == d.Machine4)\n                                {\n                                    string claimedMachineName = package.MachineName;\n\n                                    if (!remoteMachine.Equals(claimedMachineName, StringComparison.Ordinal))\n                                    {\n                                        Logger.LogDebug($\"DNS.RemoteMachineName({remoteMachine}) <> Claimed.MachineName({claimedMachineName}), using the claimed machine name.\");\n                                        remoteMachine = claimedMachineName;\n                                        currentTcp.MachineName = remoteMachine;\n                                    }\n\n                                    // Double check to avoid a redundant client socket.\n                                    if (isClient && Common.IsConnectedByAClientSocketTo(remoteMachine))\n                                    {\n                                        Logger.LogDebug(\"=====> Duplicate connected client socket for: \" + remoteMachine + \":\" + strIP + \" is being removed.\");\n                                        UpdateTcpSockets(currentTcp, SocketStatus.ForceClosed);\n                                        currentSocket.Close();\n                                        return;\n                                    }\n\n                                    if (remoteMachine.Equals(Common.MachineName, StringComparison.OrdinalIgnoreCase))\n                                    {\n                                        Logger.LogDebug(\"Connected to/from local socket: \" + strIP + (isClient ? \"-Client\" : \"-Server\"));\n                                        UpdateTcpSockets(currentTcp, SocketStatus.NA);\n                                        Common.MMSleep(1);\n                                        currentSocket.Close();\n                                        return;\n                                    }\n\n                                    packageCount = -1; // Trusted\n                                    InvalidKeyFound = false;\n                                    currentTcp.MachineId = (uint)remoteID;\n                                    currentTcp.Status = SocketStatus.Connected;\n                                    UpdateTcpSockets(currentTcp, SocketStatus.Connected);\n                                    Logger.LogDebug(\"))))))))))))))) Machine got trusted: \" + remoteMachine + \":\" + strIP + \", Is client: \" + isClient);\n\n                                    if (Math.Abs(Common.GetTick() - Common.LastReconnectByHotKeyTime) < 5000)\n                                    {\n                                        Common.ShowToolTip(\"已连接 \" + remoteMachine, 1000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);\n                                    }\n\n                                    Common.SendHeartBeat(initial: true);\n\n                                    if (Common.MachinePool.TryFindMachineByName(remoteMachine, out MachineInf machineInfo))\n                                    {\n                                        Logger.LogDebug(\"Machine updated: \" + remoteMachine + \"/\" + remoteID.ToString());\n\n                                        if (machineInfo.Name.Equals(Common.DesMachineName, StringComparison.OrdinalIgnoreCase))\n                                        {\n                                            Logger.LogDebug(\"Des ID updated: \" + Common.DesMachineID.ToString() +\n                                                \"/\" + remoteID.ToString());\n                                            Common.NewDesMachineID = Common.DesMachineID = remoteID;\n                                        }\n\n                                        _ = Common.MachinePool.TryUpdateMachineID(remoteMachine, remoteID, true);\n                                        Common.UpdateMachinePoolStringSetting();\n                                    }\n                                    else\n                                    {\n                                        Logger.LogDebug(\"New machine connected: {0}.\", remoteMachine);\n\n                                        if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                                        {\n                                            Common.ShowToolTip(\"已建立新连接 \" + remoteMachine, 1000, ToolTipIcon.Info, Setting.Values.ShowClipNetStatus);\n                                        }\n                                    }\n\n                                    if (!isClient)\n                                    {\n                                        Common.UpdateClientSockets(\"MainTCPRoutine\");\n                                    }\n                                }\n                                else\n                                {\n                                    Logger.LogDebug(\"Invalid ACK from \" + remoteMachine);\n                                    UpdateTcpSockets(currentTcp, SocketStatus.InvalidKey);\n\n                                    string remoteEP = currentSocket.RemoteEndPoint.ToString();\n\n                                    if (FailedAttempt.AddOrUpdate(remoteEP, 1, (key, value) => value + 1) > 10)\n                                    {\n                                        _ = FailedAttempt.AddOrUpdate(remoteEP, 0, (key, value) => 0);\n\n                                        _ = MessageBox.Show($\"来自 [{remoteEP}] 的连接尝试次数过多!\\r\\n重启软件后再试.\", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);\n                                        Common.MainForm.Quit(true, false);\n                                    }\n\n                                    currentSocket.Close();\n                                    break;\n                                }\n                            }\n                            else if (package.Type == PackageType.Mouse)\n                            {\n                                if (packageCount > 5)\n                                {\n                                    packageCount--;\n                                }\n                            }\n                            else if (package.Type is PackageType.Heartbeat or PackageType.Heartbeat_ex)\n                            {\n                                if (packageCount > 5)\n                                {\n                                    packageCount--;\n                                }\n                            }\n                            else\n                            {\n                                if (packageCount > 5)\n                                {\n                                    UpdateTcpSockets(currentTcp, SocketStatus.InvalidKey);\n                                }\n                                else\n                                {\n                                    Logger.Log(string.Format(\n                                        CultureInfo.CurrentCulture,\n                                        \"Unexpected package, size = {0}, type = {1}\",\n                                        receivedCount,\n                                        package.Type));\n                                }\n                            }\n                        }\n                        else if (receivedCount > 0)\n                        {\n                            // Add some log when remote machine switches.\n                            if (lastRemoteMachineID != (long)remoteID)\n                            {\n                                _ = Interlocked.Exchange(ref lastRemoteMachineID, (long)remoteID);\n                                Logger.LogDebug($\"MainTCPRoutine: Remote machine = {strIP}/{lastRemoteMachineID}\");\n                            }\n\n                            if (package.Type == PackageType.HandshakeAck)\n                            {\n                                Logger.LogDebug(\"Skipping the rest of the Handshake packages.\");\n                            }\n                            else\n                            {\n                                Receiver.ProcessPackage(package, currentTcp);\n                            }\n                        }\n                    }\n                }\n                catch (Exception e)\n                {\n                    UpdateTcpSockets(currentTcp, SocketStatus.Error);\n                    FlagReopenSocketIfNeeded(e);\n                    currentSocket.Close();\n                    Logger.Log(e);\n                    break;\n                }\n            }\n\n            if (remoteID != ID.NONE)\n            {\n                _ = Common.RemoveDeadMachines(remoteID);\n            }\n        }\n\n        private static void AcceptConnectionAndSendClipboardData(object param)\n        {\n            // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n            // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n            using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n            TcpListener server = param as TcpListener;\n\n            do\n            {\n                Logger.LogDebug(\"SendClipboardData: Waiting for request...\");\n                Socket s = null;\n\n                try\n                {\n                    s = server.AcceptSocket();\n                }\n                catch (InvalidOperationException e)\n                {\n                    Logger.Log($\"The clipboard socket could have been closed. {e.Message}\");\n                    break;\n                }\n                catch (SocketException e)\n                {\n                    if (e.ErrorCode == (int)SocketError.Interrupted)\n                    {\n                        Logger.Log(\"server.AcceptSocket: A blocking socket call was canceled.\");\n                        continue;\n                    }\n                    else\n                    {\n                        Logger.Log(e);\n                        break;\n                    }\n                }\n                catch (Exception e)\n                {\n                    Logger.Log(e);\n                    break;\n                }\n\n                if (s != null)\n                {\n                    try\n                    {\n                        new Task(() =>\n                        {\n                            // SuppressFlow fixes an issue on service mode, where the helper process can't get enough permissions to be started again.\n                            // More details can be found on: https://github.com/microsoft/PowerToys/pull/36892\n                            using var asyncFlowControl = ExecutionContext.SuppressFlow();\n\n                            System.Threading.Thread thread = Thread.CurrentThread;\n                            thread.Name = $\"{nameof(SendOrReceiveClipboardData)}.{thread.ManagedThreadId}\";\n                            Thread.UpdateThreads(thread);\n                            SendOrReceiveClipboardData(s);\n                        }).Start();\n                    }\n                    catch (Exception e)\n                    {\n                        Logger.Log(e);\n                    }\n                }\n            }\n            while (true);\n        }\n\n        internal static void SendOrReceiveClipboardData(Socket s)\n        {\n            try\n            {\n                string remoteEndPoint = s.RemoteEndPoint.ToString();\n                Logger.LogDebug(\"SendClipboardData: Request accepted: \" + s.LocalEndPoint.ToString() + \"/\" + remoteEndPoint);\n                Common.IsDropping = false;\n                Common.IsDragging = false;\n                Common.DragMachine = (ID)1;\n\n                bool clientPushData = true;\n                ClipboardPostAction postAction = ClipboardPostAction.Other;\n                bool handShaken = Common.ShakeHand(ref remoteEndPoint, s, out Stream enStream, out Stream deStream, ref clientPushData, ref postAction);\n\n                if (!handShaken)\n                {\n                    s.Close();\n                    return;\n                }\n                else\n                {\n                    Logger.LogDebug($\"{nameof(SendOrReceiveClipboardData)}: Clipboard connection accepted: \" + remoteEndPoint);\n                    Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE] { Common.ICON_SMALL_CLIPBOARD, -1, -1, -1 });\n                }\n\n                if (clientPushData)\n                {\n                    Common.ReceiveAndProcessClipboardData(remoteEndPoint, s, enStream, deStream, $\"{postAction}\");\n                }\n                else\n                {\n                    SendClipboardData(s, enStream);\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        internal static void SendClipboardData(Socket s, Stream ecStream)\n        {\n            if (Common.RunWithNoAdminRight && Setting.Values.OneWayClipboardMode)\n            {\n                s?.Close();\n                return;\n            }\n\n            const int CLOSE_TIMEOUT = 10;\n            byte[] header = new byte[1024];\n            string headerString = string.Empty;\n            if (Common.LastDragDropFile != null)\n            {\n                string fileName = null;\n\n                if (!Common.ImpersonateLoggedOnUserAndDoSomething(() =>\n                {\n                    if (!File.Exists(Common.LastDragDropFile))\n                    {\n                        headerString = Directory.Exists(Common.LastDragDropFile)\n                            ? $\"{0}*{Common.LastDragDropFile} - Folder is not supported, zip it first!\"\n                            : Common.LastDragDropFile.Contains(\"- File too big\")\n                                ? $\"{0}*{Common.LastDragDropFile}\"\n                                : $\"{0}*{Common.LastDragDropFile} not found!\";\n                    }\n                    else\n                    {\n                        fileName = Common.LastDragDropFile;\n                        headerString = $\"{new FileInfo(fileName).Length}*{fileName}\";\n                    }\n                }))\n                {\n                    s?.Close();\n                    return;\n                }\n\n                Common.GetBytesU(headerString).CopyTo(header, 0);\n\n                try\n                {\n                    ecStream.Write(header, 0, header.Length);\n\n                    if (!string.IsNullOrEmpty(fileName))\n                    {\n                        if (SendFile(s, ecStream, fileName))\n                        {\n                            s.Close(CLOSE_TIMEOUT);\n                        }\n                    }\n                    else\n                    {\n                        s.Close(CLOSE_TIMEOUT);\n                    }\n                }\n                catch (IOException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                    Logger.Log(log);\n                }\n                catch (SocketException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.\";\n                    Logger.Log(log);\n                }\n                catch (ObjectDisposedException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..\";\n                    Logger.Log(log);\n                }\n            }\n            else if (!Common.IsClipboardDataImage && Common.LastClipboardData != null)\n            {\n                try\n                {\n                    byte[] data = Common.LastClipboardData;\n\n                    headerString = $\"{data.Length}*{\"text\"}\";\n                    Common.GetBytesU(headerString).CopyTo(header, 0);\n\n                    if (data != null)\n                    {\n                        ecStream.Write(header, 0, header.Length);\n                        _ = SendData(s, ecStream, data);\n                        Logger.LogDebug(\"Text sent: \" + data.Length.ToString(CultureInfo.CurrentCulture));\n                    }\n\n                    s.Close(CLOSE_TIMEOUT);\n                }\n                catch (IOException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                    Logger.Log(log);\n                }\n                catch (SocketException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.\";\n                    Logger.Log(log);\n                }\n                catch (ObjectDisposedException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..\";\n                    Logger.Log(log);\n                }\n            }\n            else if (Common.LastClipboardData != null && Common.LastClipboardData.Length > 0)\n            {\n                byte[] data = Common.LastClipboardData;\n\n                headerString = $\"{data.Length}*{\"image\"}\";\n                Common.GetBytesU(headerString).CopyTo(header, 0);\n                try\n                {\n                    ecStream.Write(header, 0, header.Length);\n                    _ = SendData(s, ecStream, data);\n                    Logger.LogDebug(\"Image sent: \" + data.Length.ToString(CultureInfo.CurrentCulture));\n                    s.Close(CLOSE_TIMEOUT);\n                }\n                catch (IOException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                    Logger.Log(log);\n                }\n                catch (SocketException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.\";\n                    Logger.Log(log);\n                }\n                catch (ObjectDisposedException e)\n                {\n                    string log = $\"{nameof(SendClipboardData)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..\";\n                    Logger.Log(log);\n                }\n            }\n            else\n            {\n                Logger.Log(\"No data available in clipboard or LastDragDropFile!\");\n                s.Close();\n            }\n        }\n\n        private static bool SendFileEx(Socket s, Stream ecStream, string fileName)\n        {\n            try\n            {\n                using (FileStream f = File.OpenRead(fileName))\n                {\n                    byte[] buf = new byte[Common.NETWORK_STREAM_BUF_SIZE];\n                    int rv, sentCount = 0;\n\n                    do\n                    {\n                        if ((rv = f.Read(buf, 0, Common.NETWORK_STREAM_BUF_SIZE)) > 0)\n                        {\n                            ecStream.Write(buf, 0, rv);\n                            sentCount += rv;\n                        }\n                    }\n                    while (rv > 0);\n\n                    if ((rv = Common.PACKAGE_SIZE - (sentCount % Common.PACKAGE_SIZE)) > 0)\n                    {\n                        Array.Clear(buf, 0, buf.Length);\n                        ecStream.Write(buf, 0, rv);\n                    }\n\n                    ecStream.Flush();\n\n                    Logger.LogDebug(\"File sent: \" + fileName);\n                }\n\n                return true;\n            }\n            catch (Exception e)\n            {\n                if (e is IOException)\n                {\n                    string log = $\"{nameof(SendFileEx)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                    Logger.Log(log);\n                }\n                else\n                {\n                    Logger.Log(e);\n                }\n\n                Common.ShowToolTip(e.Message, 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n                s.Close();\n            }\n\n            return false;\n        }\n\n        private static bool SendFile(Socket s, Stream ecStream, string fileName)\n        {\n            bool r = false;\n\n            if (Common.RunOnLogonDesktop || Common.RunOnScrSaverDesktop)\n            {\n                if (fileName.StartsWith(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles) + @\"\\\" + Common.BinaryName + @\"\\ScreenCaptures\\\", StringComparison.CurrentCultureIgnoreCase))\n                {\n                    r = SendFileEx(s, ecStream, fileName);\n                }\n            }\n            else\n            {\n                _ = Common.ImpersonateLoggedOnUserAndDoSomething(() => { r = SendFileEx(s, ecStream, fileName); });\n            }\n\n            return r;\n        }\n\n        private static bool SendData(Socket s, Stream ecStream, byte[] data)\n        {\n            bool r = false;\n\n            try\n            {\n                using MemoryStream f = new(data);\n                byte[] buf = new byte[Common.NETWORK_STREAM_BUF_SIZE];\n                int rv, sentCount = 0;\n\n                do\n                {\n                    if ((rv = f.Read(buf, 0, Common.NETWORK_STREAM_BUF_SIZE)) > 0)\n                    {\n                        ecStream.Write(buf, 0, rv);\n                        sentCount += rv;\n                    }\n                }\n                while (rv > 0);\n\n                if ((rv = sentCount % Common.PACKAGE_SIZE) > 0)\n                {\n                    Array.Clear(buf, 0, buf.Length);\n                    ecStream.Write(buf, 0, rv);\n                }\n\n                ecStream.Flush();\n                Logger.LogDebug(\"Data sent: \" + data.Length.ToString(CultureInfo.InvariantCulture));\n                r = true;\n            }\n            catch (Exception e)\n            {\n                if (e is IOException)\n                {\n                    string log = $\"{nameof(SendData)}: Exception accessing the socket: {e.InnerException?.GetType()}/{e.Message}. (This is expected when the remote machine closes the connection during desktop switch or reconnection.)\";\n                    Logger.Log(log);\n                }\n                else\n                {\n                    Logger.Log(e);\n                }\n\n                Common.ShowToolTip(e.Message, 1000, ToolTipIcon.Warning, Setting.Values.ShowClipNetStatus);\n                ecStream.Close();\n                s.Close();\n            }\n\n            return r;\n        }\n\n        private TcpSk AddTcpSocket(bool isClient, Socket s, SocketStatus status, string machineName)\n        {\n            Common.CloseAnUnusedSocket();\n            TcpSk tcp = new(isClient, s, status, machineName);\n\n            lock (TcpSocketsLock)\n            {\n#if ENABLE_LEGACY_DOS_PROTECTION\n                PreventDoS(TcpSockets);\n#endif\n                TcpSockets.Add(tcp);\n            }\n\n            return tcp;\n        }\n\n        private TcpSk AddTcpSocket(bool isClient, Socket s, SocketStatus status, string machineName, IPAddress ip)\n        {\n            Common.CloseAnUnusedSocket();\n            TcpSk tcp = new(isClient, s, status, machineName, ip);\n\n            lock (TcpSocketsLock)\n            {\n#if ENABLE_LEGACY_DOS_PROTECTION\n                PreventDoS(TcpSockets);\n#endif\n                TcpSockets.Add(tcp);\n            }\n\n            return tcp;\n        }\n\n        private void UpdateTcpSockets(TcpSk tcp, SocketStatus status)\n        {\n            if (status == SocketStatus.InvalidKey)\n            {\n                InvalidKeyFound = true;\n            }\n\n            InvalidKeyFoundOnClientSocket = tcp.IsClient && InvalidKeyFound;\n\n            try\n            {\n                lock (TcpSocketsLock)\n                {\n                    if (TcpSockets != null)\n                    {\n                        if (status == SocketStatus.Connected && tcp.IsClient)\n                        {\n                            List<TcpSk> tobeRemovedSockets = TcpSockets;\n\n                            if (tcp.MachineId == Setting.Values.MachineId)\n                            {\n                                tcp = null;\n                                Setting.Values.MachineId = Common.Ran.Next();\n                                Common.UpdateMachineTimeAndID();\n                                Common.PleaseReopenSocket = Common.REOPEN_WHEN_HOTKEY;\n\n                                Logger.TelemetryLogTrace(\"MachineID conflict.\", SeverityLevel.Information);\n                            }\n                            else\n                            {\n                                // Keep the first connected one.\n                                tobeRemovedSockets = TcpSockets.Where(item => item.IsClient && !ReferenceEquals(item, tcp) && item.MachineName.Equals(tcp.MachineName, StringComparison.OrdinalIgnoreCase)).ToList();\n                            }\n\n                            foreach (TcpSk t in tobeRemovedSockets)\n                            {\n                                t.Status = SocketStatus.ForceClosed;\n                                Logger.LogDebug($\"Closing duplicated socket {t.MachineName}: {t.Address}\");\n                            }\n                        }\n\n                        List<TcpSk> toBeRemoved = new();\n\n                        foreach (TcpSk t in TcpSockets)\n                        {\n                            if (t.Status is SocketStatus.Error or\n                                SocketStatus.ForceClosed or\n\n                                // SocketStatus.InvalidKey or\n                                SocketStatus.NA or\n                                SocketStatus.Timeout or\n                                SocketStatus.SendError)\n                            {\n                                try\n                                {\n                                    if (t.BackingSocket != null)\n                                    {\n                                        t.MachineName = \"$*NotUsed*$\";\n                                        t.Status = t.Status >= 0 ? 0 : t.Status - 1; // If error closing, the socket will be closed again at SocketStuff.Close().\n                                        t.BackingSocket.Close();\n                                    }\n\n                                    toBeRemoved.Add(t);\n                                }\n                                catch (SocketException e)\n                                {\n                                    string log = $\"{nameof(UpdateTcpSockets)}: {e.GetType()}/{e.Message}. This is expected when the connection is closed by the remote host.\";\n                                    Logger.Log(log);\n                                }\n                                catch (ObjectDisposedException e)\n                                {\n                                    string log = $\"{nameof(UpdateTcpSockets)}: {e.GetType()}/{e.Message}. This is expected when the socket is disposed by a machine switch for ex..\";\n                                    Logger.Log(log);\n                                }\n                            }\n                        }\n\n                        if (tcp != null)\n                        {\n                            tcp.Status = status;\n\n                            if (status == SocketStatus.Connected)\n                            {\n                                // Update the socket's machine name based on its corresponding client/server socket.\n                                foreach (TcpSk t in TcpSockets)\n                                {\n                                    if (t.MachineId == tcp.MachineId && t.IsClient != tcp.IsClient)\n                                    {\n                                        if ((string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':'))\n                                            && !(string.IsNullOrEmpty(t.MachineName) || t.MachineName.Contains('.') || t.MachineName.Contains(':')))\n                                        {\n                                            tcp.MachineName = t.MachineName;\n                                        }\n                                        else if ((string.IsNullOrEmpty(t.MachineName) || t.MachineName.Contains('.') || t.MachineName.Contains(':'))\n                                            && !(string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':')))\n                                        {\n                                            t.MachineName = tcp.MachineName;\n                                        }\n                                    }\n                                }\n\n                                if (string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':'))\n                                {\n                                    tcp.MachineName = Common.NameFromID((ID)tcp.MachineId);\n                                }\n\n                                if (string.IsNullOrEmpty(tcp.MachineName) || tcp.MachineName.Contains('.') || tcp.MachineName.Contains(':'))\n                                {\n                                    tcp.MachineName = Common.GetRemoteStringIP(tcp.BackingSocket);\n                                }\n                            }\n                        }\n                        else\n                        {\n                            Logger.Log(\"UpdateTcpSockets.Exception: Socket not found!\");\n                        }\n\n                        foreach (TcpSk t in toBeRemoved)\n                        {\n                            _ = TcpSockets.Remove(t);\n                        }\n                    }\n                }\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        private void PreventDoS(List<TcpSk> sockets)\n        {\n            if (sockets.Count > 100)\n            {\n                TcpSk tcp;\n\n                try\n                {\n                    string msg = Application.ProductName + \" has been terminated, too many connections.\";\n\n                    for (int i = 0; i < 10; i++)\n                    {\n                        tcp = sockets[i * 10];\n\n                        if (tcp != null)\n                        {\n                            msg += $\"\\r\\n{Common.MachineName}{(tcp.IsClient ? \"=>\" : \"<=\")}{tcp.MachineName}:{tcp.Status}\";\n                        }\n                    }\n\n                    _ = Common.CreateLowIntegrityProcess(\n                        \"\\\"\" + Path.GetDirectoryName(Application.ExecutablePath) + \"\\\\MouseWithoutBordersHelper.exe\\\"\",\n                        \"InternalError\" + \" \\\"\" + msg + \"\\\"\",\n                        0,\n                        false,\n                        0,\n                        (short)ProcessWindowStyle.Hidden);\n                }\n                finally\n                {\n                    Common.MainForm.Quit(true, false);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Control/Machine.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.ComponentModel;\nusing System.Windows.Forms;\n\n// <summary>\n//     User control, used in the Matrix form.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Properties;\n\nnamespace MouseWithoutBorders\n{\n    internal partial class Machine : UserControl\n    {\n        // private int ip;\n        // private Point mouseDownPos;\n        private SocketStatus statusClient;\n\n        private SocketStatus statusServer;\n        private bool localhost;\n\n        internal Machine()\n        {\n            InitializeComponent();\n            Visible = false;\n            MachineEnabled = false;\n        }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal string MachineName\n        {\n            get => textBoxName.Text;\n            set => textBoxName.Text = value;\n        }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal bool MachineEnabled\n        {\n            get => checkBoxEnabled.Checked;\n            set\n            {\n                checkBoxEnabled.Checked = value;\n                Editable = value;\n                pictureBoxLogo.Image = value ? Images.MachineEnabled : (System.Drawing.Image)Images.MachineDisabled;\n                OnEnabledChanged(EventArgs.Empty); // Borrow this event since we do not use it for any other purpose:) (we can create one but l...:))\n            }\n        }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]\n        internal bool Editable\n        {\n            set => textBoxName.Enabled = value;\n\n            // get { return textBoxName.Enabled;  }\n        }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]\n        internal bool CheckAble\n        {\n            set\n            {\n                if (!value)\n                {\n                    checkBoxEnabled.Checked = true;\n                    Editable = false;\n                }\n\n                checkBoxEnabled.Enabled = value;\n            }\n        }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]\n        internal bool LocalHost\n        {\n            // get { return localhost; }\n            set\n            {\n                localhost = value;\n                if (localhost)\n                {\n                    labelStatusClient.Text = \"此电脑\";\n                    labelStatusServer.Text = \"...\";\n                    CheckAble = false;\n                }\n                else\n                {\n                    labelStatusClient.Text = \"...\";\n                    labelStatusServer.Text = \"...\";\n                    CheckAble = true;\n                }\n            }\n        }\n\n        private void PictureBoxLogo_MouseDown(object sender, MouseEventArgs e)\n        {\n            // mouseDownPos = e.Location;\n            OnMouseDown(e);\n        }\n\n        /*\n        internal Point MouseDownPos\n        {\n            get { return mouseDownPos; }\n        }\n        */\n\n        private void CheckBoxEnabled_CheckedChanged(object sender, EventArgs e)\n        {\n            MachineEnabled = checkBoxEnabled.Checked;\n        }\n\n        private static string StatusString(SocketStatus status)\n        {\n            string rv = string.Empty;\n\n            switch (status)\n            {\n                case SocketStatus.Resolving:\n                    rv = \"正在查找地址\";\n                    break;\n\n                case SocketStatus.Connected:\n                    rv = \"已连接\";\n                    break;\n\n                case SocketStatus.Connecting:\n                    rv = \"正在连接\";\n                    break;\n\n                case SocketStatus.Error:\n                    rv = \"出错\";\n                    break;\n\n                case SocketStatus.ForceClosed:\n                    rv = \"已关闭\";\n                    break;\n\n                case SocketStatus.Handshaking:\n                    rv = \"正在握手\";\n                    break;\n\n                case SocketStatus.SendError:\n                    rv = \"发送错误\";\n                    break;\n\n                case SocketStatus.InvalidKey:\n                    rv = \"密码错误\";\n                    break;\n\n                case SocketStatus.Timeout:\n                    rv = \"连接超时\";\n                    break;\n\n                case SocketStatus.NA:\n                    rv = \"...\";\n                    break;\n\n                default:\n                    break;\n            }\n\n            return rv;\n        }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal SocketStatus StatusClient\n        {\n            get => statusClient;\n\n            set\n            {\n                statusClient = value;\n                if (statusClient is SocketStatus.Connected or\n                    SocketStatus.Handshaking)\n                {\n                    Editable = false;\n                }\n\n                labelStatusClient.Text = StatusString(statusClient) + \" -->\";\n            }\n        }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal SocketStatus StatusServer\n        {\n            get => statusServer;\n\n            set\n            {\n                statusServer = value;\n                if (statusServer is SocketStatus.Connected or\n                    SocketStatus.Handshaking)\n                {\n                    Editable = false;\n                }\n\n                labelStatusServer.Text = StatusString(statusServer) + \" <--\";\n            }\n        }\n\n        private void PictureBoxLogo_Paint(object sender, PaintEventArgs e)\n        {\n            // e.Graphics.DrawString(\"(Draggable)\", this.Font, Brushes.WhiteSmoke, 20, 15);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Control/Machine.designer.cs",
    "content": "﻿namespace MouseWithoutBorders\n{\n    partial class Machine\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            this.labelStatusServer = new System.Windows.Forms.Label();\n            this.textBoxName = new System.Windows.Forms.TextBox();\n            this.checkBoxEnabled = new System.Windows.Forms.CheckBox();\n            this.pictureBoxLogo = new System.Windows.Forms.PictureBox();\n            this.labelStatusClient = new System.Windows.Forms.Label();\n            this.toolTipHelp = new System.Windows.Forms.ToolTip(this.components);\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).BeginInit();\n            this.SuspendLayout();\n            // \n            // labelStatusServer\n            // \n            this.labelStatusServer.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.labelStatusServer.Location = new System.Drawing.Point(0, 90);\n            this.labelStatusServer.Name = \"labelStatusServer\";\n            this.labelStatusServer.Size = new System.Drawing.Size(106, 16);\n            this.labelStatusServer.TabIndex = 0;\n            this.labelStatusServer.Text = \"...\";\n            this.labelStatusServer.TextAlign = System.Drawing.ContentAlignment.TopCenter;\n            // \n            // textBoxName\n            // \n            this.textBoxName.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.textBoxName.Location = new System.Drawing.Point(0, 54);\n            this.textBoxName.Name = \"textBoxName\";\n            this.textBoxName.Size = new System.Drawing.Size(106, 20);\n            this.textBoxName.TabIndex = 1;\n            this.textBoxName.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;\n            // \n            // checkBoxEnabled\n            // \n            this.checkBoxEnabled.AutoSize = true;\n            this.checkBoxEnabled.Checked = true;\n            this.checkBoxEnabled.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxEnabled.Location = new System.Drawing.Point(91, 40);\n            this.checkBoxEnabled.Name = \"checkBoxEnabled\";\n            this.checkBoxEnabled.Size = new System.Drawing.Size(15, 14);\n            this.checkBoxEnabled.TabIndex = 3;\n            this.checkBoxEnabled.UseVisualStyleBackColor = true;\n            this.checkBoxEnabled.CheckedChanged += new System.EventHandler(this.CheckBoxEnabled_CheckedChanged);\n            // \n            // pictureBoxLogo\n            // \n            this.pictureBoxLogo.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.pictureBoxLogo.ErrorImage = null;\n            this.pictureBoxLogo.InitialImage = null;\n            this.pictureBoxLogo.Location = new System.Drawing.Point(0, 0);\n            this.pictureBoxLogo.Name = \"pictureBoxLogo\";\n            this.pictureBoxLogo.Size = new System.Drawing.Size(106, 54);\n            this.pictureBoxLogo.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;\n            this.pictureBoxLogo.TabIndex = 2;\n            this.pictureBoxLogo.TabStop = false;\n            this.toolTipHelp.SetToolTip(this.pictureBoxLogo, \"拖放改变设备布局，选中输入设备名称。\");\n            this.pictureBoxLogo.Paint += new System.Windows.Forms.PaintEventHandler(this.PictureBoxLogo_Paint);\n            this.pictureBoxLogo.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PictureBoxLogo_MouseDown);\n            // \n            // labelStatusClient\n            // \n            this.labelStatusClient.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.labelStatusClient.Location = new System.Drawing.Point(0, 74);\n            this.labelStatusClient.Name = \"labelStatusClient\";\n            this.labelStatusClient.Size = new System.Drawing.Size(106, 16);\n            this.labelStatusClient.TabIndex = 4;\n            this.labelStatusClient.Text = \"...\";\n            this.labelStatusClient.TextAlign = System.Drawing.ContentAlignment.TopCenter;\n            // \n            // Machine\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.Transparent;\n            this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Stretch;\n            this.Controls.Add(this.checkBoxEnabled);\n            this.Controls.Add(this.pictureBoxLogo);\n            this.Controls.Add(this.textBoxName);\n            this.Controls.Add(this.labelStatusClient);\n            this.Controls.Add(this.labelStatusServer);\n            this.Name = \"Machine\";\n            this.Size = new System.Drawing.Size(106, 106);\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxLogo)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label labelStatusServer;\n        private System.Windows.Forms.TextBox textBoxName;\n        private System.Windows.Forms.PictureBox pictureBoxLogo;\n        private System.Windows.Forms.CheckBox checkBoxEnabled;\n        private System.Windows.Forms.Label labelStatusClient;\n        private System.Windows.Forms.ToolTip toolTipHelp;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Core/Receiver.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Threading.Tasks;\nusing System.Windows.Forms;\n\nusing MouseWithoutBorders.Class;\n\n[module: SuppressMessage(\"Microsoft.Reliability\", \"CA2002:DoNotLockOnObjectsWithWeakIdentity\", Scope = \"member\", Target = \"MouseWithoutBorders.Common.#PreProcess(MouseWithoutBorders.DATA)\", Justification = \"Dotnet port with style preservation\")]\n\n// <summary>\n//     Back-end thread for the socket.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nnamespace MouseWithoutBorders.Core;\n\ninternal static class Receiver\n{\n    private static readonly uint QUEUE_SIZE = 50;\n    private static readonly int[] RecentProcessedPackageIDs = new int[QUEUE_SIZE];\n    private static int recentProcessedPackageIndex;\n#pragma warning disable SA1307 // Accessible fields should begin with upper-case letter\n    internal static long processedPackageCount;\n    internal static long skippedPackageCount;\n#pragma warning restore SA1307\n\n    private static long JustGotAKey { get; set; }\n\n    private static bool PreProcess(DATA package)\n    {\n        if (package.Type == PackageType.Invalid)\n        {\n            if ((Common.InvalidPackageCount % 100) == 0)\n            {\n                Common.ShowToolTip(\"收到无效数据包!\", 1000, ToolTipIcon.Warning, false);\n            }\n\n            Common.InvalidPackageCount++;\n            Logger.Log(\"Invalid packages received!\");\n            return false;\n        }\n        else if (package.Type == 0)\n        {\n            Logger.Log(\"Got an unknown package!\");\n            return false;\n        }\n        else if (package.Type is not PackageType.ClipboardText and not PackageType.ClipboardImage\n\n            // BEGIN: These package types are sent by TcpSend which is single direction.\n            and not PackageType.Handshake and not PackageType.HandshakeAck)\n        {\n            // END\n            lock (RecentProcessedPackageIDs)\n            {\n                for (int i = 0; i < QUEUE_SIZE; i++)\n                {\n                    if (RecentProcessedPackageIDs[i] == package.Id)\n                    {\n                        skippedPackageCount++;\n                        return false;\n                    }\n                }\n\n                processedPackageCount++;\n                recentProcessedPackageIndex = (int)((recentProcessedPackageIndex + 1) % QUEUE_SIZE);\n                RecentProcessedPackageIDs[recentProcessedPackageIndex] = package.Id;\n            }\n        }\n\n        return true;\n    }\n\n    private static System.Drawing.Point lastXY;\n\n    internal static void ProcessPackage(DATA package, TcpSk tcp)\n    {\n        if (!PreProcess(package))\n        {\n            return;\n        }\n\n        switch (package.Type)\n        {\n            case PackageType.Keyboard:\n                Common.PackageReceived.Keyboard++;\n                if (package.Des == Common.MachineID || package.Des == ID.ALL)\n                {\n                    JustGotAKey = Common.GetTick();\n\n                    // NOTE(@yuyoyuppe): disabled to drop elevation requirement\n                    bool nonElevated = Common.RunWithNoAdminRight && false;\n                    if (nonElevated && Setting.Values.OneWayControlMode)\n                    {\n                        if ((package.Kd.dwFlags & (int)Common.LLKHF.UP) == (int)Common.LLKHF.UP)\n                        {\n                            Common.ShowOneWayModeMessage();\n                        }\n\n                        return;\n                    }\n\n                    InputSimulation.SendKey(package.Kd);\n                }\n\n                break;\n\n            case PackageType.Mouse:\n                Common.PackageReceived.Mouse++;\n\n                if (package.Des == Common.MachineID || package.Des == ID.ALL)\n                {\n                    if (Common.desMachineID != Common.MachineID)\n                    {\n                        Common.NewDesMachineID = Common.DesMachineID = Common.MachineID;\n                    }\n\n                    // NOTE(@yuyoyuppe): disabled to drop elevation requirement\n                    bool nonElevated = Common.RunWithNoAdminRight && false;\n                    if (nonElevated && Setting.Values.OneWayControlMode && package.Md.dwFlags != Common.WM_MOUSEMOVE)\n                    {\n                        if (!Common.IsDropping)\n                        {\n                            if (package.Md.dwFlags is Common.WM_LBUTTONDOWN or Common.WM_RBUTTONDOWN)\n                            {\n                                Common.ShowOneWayModeMessage();\n                            }\n                        }\n                        else if (package.Md.dwFlags is Common.WM_LBUTTONUP or Common.WM_RBUTTONUP)\n                        {\n                            Common.IsDropping = false;\n                        }\n\n                        return;\n                    }\n\n                    if (Math.Abs(package.Md.X) >= Common.MOVE_MOUSE_RELATIVE && Math.Abs(package.Md.Y) >= Common.MOVE_MOUSE_RELATIVE)\n                    {\n                        if (package.Md.dwFlags == Common.WM_MOUSEMOVE)\n                        {\n                            InputSimulation.MoveMouseRelative(\n                                package.Md.X < 0 ? package.Md.X + Common.MOVE_MOUSE_RELATIVE : package.Md.X - Common.MOVE_MOUSE_RELATIVE,\n                                package.Md.Y < 0 ? package.Md.Y + Common.MOVE_MOUSE_RELATIVE : package.Md.Y - Common.MOVE_MOUSE_RELATIVE);\n                            _ = NativeMethods.GetCursorPos(ref lastXY);\n\n                            Point p = Common.MoveToMyNeighbourIfNeeded(lastXY.X, lastXY.Y, Common.MachineID);\n\n                            if (!p.IsEmpty)\n                            {\n                                Common.HasSwitchedMachineSinceLastCopy = true;\n\n                                Logger.LogDebug(string.Format(\n                                    CultureInfo.CurrentCulture,\n                                    \"***** Controlled Machine: newDesMachineIdEx set = [{0}]. Mouse is now at ({1},{2})\",\n                                    Common.newDesMachineIdEx,\n                                    lastXY.X,\n                                    lastXY.Y));\n\n                                Common.SendNextMachine(package.Src, Common.newDesMachineIdEx, p);\n                            }\n                        }\n                        else\n                        {\n                            _ = NativeMethods.GetCursorPos(ref lastXY);\n                            package.Md.X = lastXY.X * 65535 / Common.screenWidth;\n                            package.Md.Y = lastXY.Y * 65535 / Common.screenHeight;\n                            _ = InputSimulation.SendMouse(package.Md);\n                        }\n                    }\n                    else\n                    {\n                        _ = InputSimulation.SendMouse(package.Md);\n                        _ = NativeMethods.GetCursorPos(ref lastXY);\n                    }\n\n                    Common.LastX = lastXY.X;\n                    Common.LastY = lastXY.Y;\n                    CustomCursor.ShowFakeMouseCursor(Common.LastX, Common.LastY);\n                }\n\n                Common.DragDropStep01(package.Md.dwFlags);\n                Common.DragDropStep09(package.Md.dwFlags);\n                break;\n\n            case PackageType.NextMachine:\n                Logger.LogDebug(\"PackageType.NextMachine received!\");\n\n                if (Common.IsSwitchingByMouseEnabled())\n                {\n                    Common.PrepareToSwitchToMachine((ID)package.Md.WheelDelta, new Point(package.Md.X, package.Md.Y));\n                }\n\n                break;\n\n            case PackageType.ExplorerDragDrop:\n                Common.PackageReceived.ExplorerDragDrop++;\n                Common.DragDropStep03(package);\n                break;\n\n            case PackageType.Heartbeat:\n            case PackageType.Heartbeat_ex:\n                Common.PackageReceived.Heartbeat++;\n\n                Common.GeneratedKey = Common.GeneratedKey || package.Type == PackageType.Heartbeat_ex;\n\n                if (Common.GeneratedKey)\n                {\n                    Setting.Values.MyKey = Common.MyKey;\n                    Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l2);\n                }\n\n                string desMachine = Common.AddToMachinePool(package);\n\n                if (Setting.Values.FirstRun && !string.IsNullOrEmpty(desMachine))\n                {\n                    Common.UpdateSetupMachineMatrix(desMachine);\n                    Common.UpdateClientSockets(\"UpdateSetupMachineMatrix\");\n                }\n\n                break;\n\n            case PackageType.Heartbeat_ex_l2:\n                Common.GeneratedKey = true;\n                Setting.Values.MyKey = Common.MyKey;\n                Common.SendPackage(ID.ALL, PackageType.Heartbeat_ex_l3);\n\n                break;\n\n            case PackageType.Heartbeat_ex_l3:\n                Common.GeneratedKey = true;\n                Setting.Values.MyKey = Common.MyKey;\n\n                break;\n\n            case PackageType.Awake:\n                Common.PackageReceived.Heartbeat++;\n                _ = Common.AddToMachinePool(package);\n                Common.HumanBeingDetected();\n                break;\n\n            case PackageType.Hello:\n                Common.PackageReceived.Hello++;\n                Common.SendHeartBeat();\n                string newMachine = Common.AddToMachinePool(package);\n                if (Setting.Values.MachineMatrixString == null)\n                {\n                    string tip = newMachine + \" 报到!\";\n                    tip += \"\\r\\n 右键打开设备布局\";\n                    Common.ShowToolTip(tip);\n                }\n\n                break;\n\n            case PackageType.Hi:\n                Common.PackageReceived.Hello++;\n                break;\n\n            case PackageType.ByeBye:\n                Common.PackageReceived.ByeBye++;\n                Common.ProcessByeByeMessage(package);\n                break;\n\n            case PackageType.Clipboard:\n                Common.PackageReceived.Clipboard++;\n                if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                {\n                    Common.clipboardCopiedTime = Common.GetTick();\n                    GetNameOfMachineWithClipboardData(package);\n                    SignalBigClipboardData();\n                }\n\n                break;\n\n            case PackageType.MachineSwitched:\n                if (Common.GetTick() - Common.clipboardCopiedTime < Common.BIG_CLIPBOARD_DATA_TIMEOUT && (package.Des == Common.MachineID))\n                {\n                    Common.clipboardCopiedTime = 0;\n                    Common.GetRemoteClipboard(\"PackageType.MachineSwitched\");\n                }\n\n                break;\n\n            case PackageType.ClipboardCapture:\n                Common.PackageReceived.Clipboard++;\n                if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                {\n                    if (package.Des == Common.MachineID || package.Des == ID.ALL)\n                    {\n                        GetNameOfMachineWithClipboardData(package);\n                        Common.GetRemoteClipboard(\"mspaint,\" + Common.LastMachineWithClipboardData);\n                    }\n                }\n\n                break;\n\n            case PackageType.CaptureScreenCommand:\n                Common.PackageReceived.Clipboard++;\n                if (package.Des == Common.MachineID || package.Des == ID.ALL)\n                {\n                    Common.SendImage(package.Src, Common.CaptureScreen());\n                }\n\n                break;\n\n            case PackageType.ClipboardAsk:\n                Common.PackageReceived.ClipboardAsk++;\n\n                if (package.Des == Common.MachineID)\n                {\n                    _ = Task.Run(() =>\n                    {\n                        try\n                        {\n                            System.Threading.Thread thread = Thread.CurrentThread;\n                            thread.Name = $\"{nameof(PackageType.ClipboardAsk)}.{thread.ManagedThreadId}\";\n                            Thread.UpdateThreads(thread);\n\n                            string remoteMachine = package.MachineName;\n                            System.Net.Sockets.TcpClient client = Common.ConnectToRemoteClipboardSocket(remoteMachine);\n                            bool clientPushData = true;\n\n                            if (Common.ShakeHand(ref remoteMachine, client.Client, out Stream enStream, out Stream deStream, ref clientPushData, ref package.PostAction))\n                            {\n                                SocketStuff.SendClipboardData(client.Client, enStream);\n                            }\n                        }\n                        catch (Exception e)\n                        {\n                            Logger.Log(e);\n                        }\n                    });\n                }\n\n                break;\n\n            case PackageType.ClipboardDragDrop:\n                Common.PackageReceived.ClipboardDragDrop++;\n                Common.DragDropStep08(package);\n                break;\n\n            case PackageType.ClipboardDragDropOperation:\n                Common.PackageReceived.ClipboardDragDrop++;\n                Common.DragDropStep08_2(package);\n                break;\n\n            case PackageType.ClipboardDragDropEnd:\n                Common.PackageReceived.ClipboardDragDropEnd++;\n                Common.DragDropStep12();\n                break;\n\n            case PackageType.ClipboardText:\n            case PackageType.ClipboardImage:\n                Common.clipboardCopiedTime = 0;\n                if (package.Type == PackageType.ClipboardImage)\n                {\n                    Common.PackageReceived.ClipboardImage++;\n                }\n                else\n                {\n                    Common.PackageReceived.ClipboardText++;\n                }\n\n                if (tcp != null)\n                {\n                    Common.ReceiveClipboardDataUsingTCP(\n                        package,\n                        package.Type == PackageType.ClipboardImage,\n                        tcp);\n                }\n\n                break;\n\n            case PackageType.HideMouse:\n                Common.HasSwitchedMachineSinceLastCopy = true;\n                Common.HideMouseCursor(true);\n                Common.MainFormDotEx(false);\n                Common.ReleaseAllKeys();\n                break;\n\n            default:\n                if ((package.Type & PackageType.Matrix) == PackageType.Matrix)\n                {\n                    Common.PackageReceived.Matrix++;\n                    Common.UpdateMachineMatrix(package);\n                    break;\n                }\n                else\n                {\n                    // We should never get to this point!\n                    Logger.Log(\"Invalid package received!\");\n                    return;\n                }\n        }\n    }\n\n    internal static void GetNameOfMachineWithClipboardData(DATA package)\n    {\n        Common.LastIDWithClipboardData = package.Src;\n        List<MachineInf> matchingMachines = Common.MachinePool.TryFindMachineByID(Common.LastIDWithClipboardData);\n        if (matchingMachines.Count >= 1)\n        {\n            Common.LastMachineWithClipboardData = matchingMachines[0].Name.Trim();\n        }\n\n        /*\n        lastMachineWithClipboardData =\n            Common.GetString(BitConverter.GetBytes(package.machineNameHead));\n        lastMachineWithClipboardData +=\n            Common.GetString(BitConverter.GetBytes(package.machineNameTail));\n        lastMachineWithClipboardData = lastMachineWithClipboardData.Trim();\n         * */\n    }\n\n    private static void SignalBigClipboardData()\n    {\n        Logger.LogDebug(\"SignalBigClipboardData\");\n        Common.SetToggleIcon(new int[Common.TOGGLE_ICONS_SIZE] { Common.ICON_BIG_CLIPBOARD, -1, Common.ICON_BIG_CLIPBOARD, -1 });\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsFormPage.Designer.cs",
    "content": "﻿namespace MouseWithoutBorders\n{\n    partial class SettingsFormPage\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.buttonSkip = new System.Windows.Forms.Button();\n            this.BackButton = new MouseWithoutBorders.ImageButton();\n            ((System.ComponentModel.ISupportInitialize)(this.BackButton)).BeginInit();\n            this.SuspendLayout();\n            // \n            // buttonSkip\n            // \n            this.buttonSkip.FlatAppearance.BorderSize = 0;\n            this.buttonSkip.FlatAppearance.MouseDownBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(192)))), ((int)(((byte)(128)))));\n            this.buttonSkip.FlatAppearance.MouseOverBackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(128)))), ((int)(((byte)(0)))));\n            this.buttonSkip.FlatStyle = System.Windows.Forms.FlatStyle.Flat;\n            this.buttonSkip.ForeColor = System.Drawing.Color.White;\n            this.buttonSkip.Location = new System.Drawing.Point(0, 36);\n            this.buttonSkip.Name = \"buttonSkip\";\n            this.buttonSkip.Size = new System.Drawing.Size(40, 23);\n            this.buttonSkip.TabIndex = 1;\n            this.buttonSkip.Text = \"跳过(&S)\";\n            this.buttonSkip.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;\n            this.buttonSkip.UseVisualStyleBackColor = true;\n            this.buttonSkip.Click += new System.EventHandler(this.ButtonSkip_Click);\n            // \n            // BackButton\n            // \n            this.BackButton.DisabledImage = null;\n            this.BackButton.DownImage = global::MouseWithoutBorders.Properties.Images.back_button_click;\n            this.BackButton.HoverImage = global::MouseWithoutBorders.Properties.Images.back_button_hover;\n            this.BackButton.Image = global::MouseWithoutBorders.Properties.Images.back_button_normal;\n            this.BackButton.Location = new System.Drawing.Point(6, 6);\n            this.BackButton.Name = \"BackButton\";\n            this.BackButton.NormalImage = global::MouseWithoutBorders.Properties.Images.back_button_normal;\n            this.BackButton.Size = new System.Drawing.Size(24, 24);\n            this.BackButton.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;\n            this.BackButton.TabIndex = 0;\n            this.BackButton.TabStop = false;\n            this.BackButton.Visible = false;\n            this.BackButton.Click += new System.EventHandler(this.BackButton_Click);\n            // \n            // SettingsFormPage\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.DeepSkyBlue;\n            this.Controls.Add(this.buttonSkip);\n            this.Controls.Add(this.BackButton);\n            this.Name = \"SettingsFormPage\";\n            this.Size = new System.Drawing.Size(396, 345);\n            ((System.ComponentModel.ISupportInitialize)(this.BackButton)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private ImageButton BackButton;\n        private System.Windows.Forms.Button buttonSkip;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SettingsFormPage.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Windows.Forms;\n\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Form.Settings;\n\nnamespace MouseWithoutBorders\n{\n    public partial class SettingsFormPage : UserControl\n    {\n        public event EventHandler<PageEventArgs> NextPage;\n\n        protected bool BackButtonVisible\n        {\n            get => BackButton.Visible;\n            set => BackButton.Visible = value;\n        }\n\n        public SettingsFormPage()\n        {\n            InitializeComponent();\n        }\n\n        public virtual void OnPageClosing()\n        {\n        }\n\n        protected void SendNextPage(SettingsFormPage page)\n        {\n            NextPage?.Invoke(this, new PageEventArgs(page));\n        }\n\n        protected virtual SettingsFormPage CreateBackPage()\n        {\n            return null;\n        }\n\n        protected string GetSecureKey()\n        {\n            return Common.MyKey;\n        }\n\n        private void BackButton_Click(object sender, EventArgs e)\n        {\n            SendNextPage(CreateBackPage());\n        }\n\n        private void ButtonSkip_Click(object sender, EventArgs e)\n        {\n            if (MessageBox.Show(\n                \"强烈推荐您先完成初始配置！确定需要跳过这些步骤吗？\",\n                Application.ProductName,\n                MessageBoxButtons.YesNo,\n                MessageBoxIcon.Warning,\n                MessageBoxDefaultButton.Button2) == DialogResult.Yes)\n            {\n                Setting.Values.FirstRun = false;\n                Common.CloseSetupForm();\n                Common.ShowMachineMatrix();\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage1.Designer.cs",
    "content": "﻿using System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    partial class SetupPage1\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.panel1 = new System.Windows.Forms.Panel();\n            this.label1 = new System.Windows.Forms.Label();\n            this.panel2 = new System.Windows.Forms.Panel();\n            this.label2 = new System.Windows.Forms.Label();\n            this.label3 = new System.Windows.Forms.Label();\n            this.label4 = new System.Windows.Forms.Label();\n            this.NoButton = new MouseWithoutBorders.ImageButton();\n            this.YesButton = new MouseWithoutBorders.ImageButton();\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\n            ((System.ComponentModel.ISupportInitialize)(this.NoButton)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.YesButton)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\n            this.SuspendLayout();\n            // \n            // panel1\n            // \n            this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel1.BackColor = System.Drawing.Color.White;\n            this.panel1.Location = new System.Drawing.Point(41, 96);\n            this.panel1.Name = \"panel1\";\n            this.panel1.Size = new System.Drawing.Size(370, 1);\n            this.panel1.TabIndex = 1;\n            // \n            // label1\n            // \n            this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label1.ForeColor = System.Drawing.Color.White;\n            this.label1.Location = new System.Drawing.Point(61, 102);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(330, 52);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"让我们开始吧\";\n            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // panel2\n            // \n            this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel2.BackColor = System.Drawing.Color.White;\n            this.panel2.Location = new System.Drawing.Point(41, 166);\n            this.panel2.Name = \"panel2\";\n            this.panel2.Size = new System.Drawing.Size(370, 1);\n            this.panel2.TabIndex = 2;\n            // \n            // label2\n            // \n            this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label2.ForeColor = System.Drawing.Color.White;\n            this.label2.Location = new System.Drawing.Point(61, 185);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(310, 40);\n            this.label2.TabIndex = 3;\n            this.label2.Text = \"我们需要知道您是否已经在要连接的电脑上完成了配置。\";\n            // \n            // label3\n            // \n            this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label3.ForeColor = System.Drawing.Color.White;\n            this.label3.Location = new System.Drawing.Point(61, 240);\n            this.label3.Name = \"label3\";\n            this.label3.Size = new System.Drawing.Size(310, 60);\n            this.label3.TabIndex = 4;            \n            this.label3.Text = \"您是否已经在另一台电脑上安装了无界鼠标？\";\n            // \n            // label4\n            // \n            this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label4.ForeColor = System.Drawing.Color.White;\n            this.label4.Location = new System.Drawing.Point(61, 278);\n            this.label4.Name = \"label4\";\n            this.label4.Size = new System.Drawing.Size(310, 20);\n            this.label4.TabIndex = 5;\n            this.label4.Text = \"\";\n            // \n            // NoButton\n            // \n            this.NoButton.BackColor = System.Drawing.Color.Transparent;\n            this.NoButton.DisabledImage = null;\n            this.NoButton.DownImage = global::MouseWithoutBorders.Properties.Images.no_button_click;\n            this.NoButton.HoverImage = global::MouseWithoutBorders.Properties.Images.no_button_hover;\n            this.NoButton.Image = global::MouseWithoutBorders.Properties.Images.no_button_normal;\n            this.NoButton.InitialImage = global::MouseWithoutBorders.Properties.Images.yes_button_normal;\n            this.NoButton.Location = new System.Drawing.Point(234, 366);\n            this.NoButton.Name = \"NoButton\";\n            this.NoButton.NormalImage = global::MouseWithoutBorders.Properties.Images.no_button_normal;\n            this.NoButton.Size = new System.Drawing.Size(55, 55);\n            this.NoButton.TabIndex = 7;\n            this.NoButton.TabStop = false;\n            this.NoButton.Click += new System.EventHandler(this.NoButtonClick);\n            // \n            // YesButton\n            // \n            this.YesButton.BackColor = System.Drawing.Color.Transparent;\n            this.YesButton.DisabledImage = null;\n            this.YesButton.DownImage = global::MouseWithoutBorders.Properties.Images.yes_button_click;\n            this.YesButton.HoverImage = global::MouseWithoutBorders.Properties.Images.yes_button_hover;\n            this.YesButton.Image = global::MouseWithoutBorders.Properties.Images.yes_button_normal;\n            this.YesButton.InitialImage = global::MouseWithoutBorders.Properties.Images.yes_button_normal;\n            this.YesButton.Location = new System.Drawing.Point(164, 366);\n            this.YesButton.Name = \"YesButton\";\n            this.YesButton.NormalImage = global::MouseWithoutBorders.Properties.Images.yes_button_normal;\n            this.YesButton.Size = new System.Drawing.Size(55, 55);\n            this.YesButton.TabIndex = 6;\n            this.YesButton.TabStop = false;\n            this.YesButton.Click += new System.EventHandler(this.YesButtonClick);\n            // \n            // pictureBox1\n            // \n            this.pictureBox1.Image = global::MouseWithoutBorders.Properties.Images.Mouse;\n            this.pictureBox1.Location = new System.Drawing.Point(206, 40);\n            this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);\n            this.pictureBox1.Name = \"pictureBox1\";\n            this.pictureBox1.Size = new System.Drawing.Size(41, 36);\n            this.pictureBox1.TabIndex = 0;\n            this.pictureBox1.TabStop = false;\n            // \n            // SetupPage1\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.NoButton);\n            this.Controls.Add(this.YesButton);\n            this.Controls.Add(this.label4);\n            this.Controls.Add(this.label3);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.panel2);\n            this.Controls.Add(this.label1);\n            this.Controls.Add(this.panel1);\n            this.Controls.Add(this.pictureBox1);\n            this.DoubleBuffered = true;\n            this.Name = \"SetupPage1\";\n            this.Size = new System.Drawing.Size(453, 438);\n            this.Controls.SetChildIndex(this.pictureBox1, 0);\n            this.Controls.SetChildIndex(this.panel1, 0);\n            this.Controls.SetChildIndex(this.label1, 0);\n            this.Controls.SetChildIndex(this.panel2, 0);\n            this.Controls.SetChildIndex(this.label2, 0);\n            this.Controls.SetChildIndex(this.label3, 0);\n            this.Controls.SetChildIndex(this.label4, 0);\n            this.Controls.SetChildIndex(this.YesButton, 0);\n            this.Controls.SetChildIndex(this.NoButton, 0);\n            ((System.ComponentModel.ISupportInitialize)(this.NoButton)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.YesButton)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.PictureBox pictureBox1;\n        private System.Windows.Forms.Panel panel1;\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Panel panel2;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.Label label3;\n        private System.Windows.Forms.Label label4;\n        private ImageButton YesButton;\n        private ImageButton NoButton;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2a.Designer.cs",
    "content": "namespace MouseWithoutBorders\n{\n    using System.Windows.Forms;\n\n    partial class SetupPage2a\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.label6 = new System.Windows.Forms.Label();\n            this.SecurityCodeField = new MouseWithoutBorders.ColorBorderField();\n            this.ComputerNameField = new MouseWithoutBorders.ColorBorderField();\n            this.label3 = new System.Windows.Forms.Label();\n            this.LinkButton = new MouseWithoutBorders.ImageButton();\n            this.label2 = new System.Windows.Forms.Label();\n            this.ExpandHelpButton = new MouseWithoutBorders.ImageButton();\n            this.CollapseHelpButton = new MouseWithoutBorders.ImageButton();\n            this.HelpLabel = new System.Windows.Forms.Label();\n            ((System.ComponentModel.ISupportInitialize)(this.LinkButton)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).BeginInit();\n            this.SuspendLayout();\n            // \n            // label6\n            // \n            this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.label6.Location = new System.Drawing.Point(98, 208);\n            this.label6.Name = \"label6\";\n            this.label6.Size = new System.Drawing.Size(130, 18);\n            this.label6.TabIndex = 7;\n            this.label6.Text = \"\";\n            this.label6.TextAlign = System.Drawing.ContentAlignment.BottomLeft;\n            // \n            // SecurityCodeField\n            // \n            this.SecurityCodeField.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.SecurityCodeField.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.SecurityCodeField.BorderSize = 2;\n            this.SecurityCodeField.FocusColor = System.Drawing.Color.FromArgb(((int)(((byte)(251)))), ((int)(((byte)(176)))), ((int)(((byte)(64)))));\n            this.SecurityCodeField.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.SecurityCodeField.Location = new System.Drawing.Point(80, 226);\n            this.SecurityCodeField.Margin = new System.Windows.Forms.Padding(0);\n            this.SecurityCodeField.MaximumLength = 22;\n            this.SecurityCodeField.Name = \"SecurityCodeField\";\n            this.SecurityCodeField.Size = new System.Drawing.Size(300, 30);\n            this.SecurityCodeField.TabIndex = 0;\n            this.SecurityCodeField.FieldTextChanged += new System.EventHandler(this.SecurityCodeFieldFieldTextChanged);\n            // \n            // ComputerNameField\n            // \n            this.ComputerNameField.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.ComputerNameField.BorderColor = System.Drawing.Color.FromArgb(((int)(((byte)(177)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.ComputerNameField.BorderSize = 2;\n            this.ComputerNameField.FocusColor = System.Drawing.Color.FromArgb(((int)(((byte)(251)))), ((int)(((byte)(176)))), ((int)(((byte)(64)))));\n            this.ComputerNameField.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F);\n            this.ComputerNameField.Location = new System.Drawing.Point(80, 280);\n            this.ComputerNameField.Margin = new System.Windows.Forms.Padding(0);\n            this.ComputerNameField.MaximumLength = 126;\n            this.ComputerNameField.Name = \"ComputerNameField\";\n            this.ComputerNameField.Size = new System.Drawing.Size(300, 30);\n            this.ComputerNameField.TabIndex = 1;\n            this.ComputerNameField.FieldTextChanged += new System.EventHandler(this.ComputerNameFieldFieldTextChanged);\n            // \n            // label3\n            // \n            this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label3.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.label3.Location = new System.Drawing.Point(98, 262);\n            this.label3.Name = \"label3\";\n            this.label3.Size = new System.Drawing.Size(262, 18);\n            this.label3.TabIndex = 13;\n            this.label3.Text = \"豸\";\n            this.label3.TextAlign = System.Drawing.ContentAlignment.BottomLeft;\n            // \n            // LinkButton\n            // \n            this.LinkButton.DisabledImage = global::MouseWithoutBorders.Properties.Images.link_button_disabled;\n            this.LinkButton.DownImage = global::MouseWithoutBorders.Properties.Images.link_button_click;\n            this.LinkButton.Enabled = false;\n            this.LinkButton.HoverImage = global::MouseWithoutBorders.Properties.Images.link_button_hover;\n            this.LinkButton.Image = global::MouseWithoutBorders.Properties.Images.link_button_normal;\n            this.LinkButton.Location = new System.Drawing.Point(199, 366);\n            this.LinkButton.Name = \"LinkButton\";\n            this.LinkButton.NormalImage = global::MouseWithoutBorders.Properties.Images.link_button_normal;\n            this.LinkButton.Size = new System.Drawing.Size(55, 55);\n            this.LinkButton.TabIndex = 15;\n            this.LinkButton.TabStop = false;\n            this.LinkButton.Click += new System.EventHandler(this.LinkButtonClick);\n            // \n            // label2\n            // \n            this.label2.AutoSize = true;\n            this.label2.BackColor = System.Drawing.Color.Transparent;\n            this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label2.ForeColor = System.Drawing.Color.White;\n            this.label2.Location = new System.Drawing.Point(213, 208);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(128, 16);\n            this.label2.TabIndex = 23;\n            this.label2.Text = \"ȥ룿\";\n            // \n            // ExpandHelpButton\n            // \n            this.ExpandHelpButton.DisabledImage = null;\n            this.ExpandHelpButton.DownImage = global::MouseWithoutBorders.Properties.Images.expand_button_click;\n            this.ExpandHelpButton.HoverImage = global::MouseWithoutBorders.Properties.Images.expand_button_highlight;\n            this.ExpandHelpButton.Image = global::MouseWithoutBorders.Properties.Images.expand_button_normal;\n            this.ExpandHelpButton.Location = new System.Drawing.Point(360, 211);\n            this.ExpandHelpButton.Name = \"ExpandHelpButton\";\n            this.ExpandHelpButton.NormalImage = global::MouseWithoutBorders.Properties.Images.expand_button_normal;\n            this.ExpandHelpButton.Size = new System.Drawing.Size(11, 11);\n            this.ExpandHelpButton.TabIndex = 24;\n            this.ExpandHelpButton.TabStop = false;\n            this.ExpandHelpButton.Click += new System.EventHandler(this.ExpandHelpButtonClick);\n            // \n            // CollapseHelpButton\n            // \n            this.CollapseHelpButton.DisabledImage = null;\n            this.CollapseHelpButton.DownImage = global::MouseWithoutBorders.Properties.Images.collapse_button_click;\n            this.CollapseHelpButton.HoverImage = global::MouseWithoutBorders.Properties.Images.collapse_button_hover;\n            this.CollapseHelpButton.Image = global::MouseWithoutBorders.Properties.Images.collapse_button_normal;\n            this.CollapseHelpButton.Location = new System.Drawing.Point(360, 211);\n            this.CollapseHelpButton.Name = \"CollapseHelpButton\";\n            this.CollapseHelpButton.NormalImage = global::MouseWithoutBorders.Properties.Images.collapse_button_normal;\n            this.CollapseHelpButton.Size = new System.Drawing.Size(11, 11);\n            this.CollapseHelpButton.TabIndex = 25;\n            this.CollapseHelpButton.TabStop = false;\n            this.CollapseHelpButton.Visible = false;\n            this.CollapseHelpButton.Click += new System.EventHandler(this.CollapseHelpButtonClick);\n            // \n            // HelpLabel\n            // \n            this.HelpLabel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(49)))), ((int)(((byte)(159)))), ((int)(((byte)(217)))));\n            this.HelpLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.HelpLabel.ForeColor = System.Drawing.Color.White;\n            this.HelpLabel.Location = new System.Drawing.Point(101, 226);\n            this.HelpLabel.Name = \"HelpLabel\";\n            this.HelpLabel.Size = new System.Drawing.Size(250, 94);\n            this.HelpLabel.TabIndex = 26;\n            this.HelpLabel.Text = \"ҪӵĵϣҼ޽ͼ꣬ý棬нչʾ롣豸һ̨Եơ\";\n            this.HelpLabel.Visible = false;\n            // \n            // SetupPage2a\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.HelpLabel);\n            this.Controls.Add(this.LinkButton);\n            this.Controls.Add(this.ComputerNameField);\n            this.Controls.Add(this.label3);\n            this.Controls.Add(this.SecurityCodeField);\n            this.Controls.Add(this.CollapseHelpButton);\n            this.Controls.Add(this.ExpandHelpButton);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.label6);\n            this.DoubleBuffered = true;\n            this.Name = \"SetupPage2a\";\n            this.Size = new System.Drawing.Size(453, 438);\n            this.Controls.SetChildIndex(this.label6, 0);\n            this.Controls.SetChildIndex(this.label2, 0);\n            this.Controls.SetChildIndex(this.ExpandHelpButton, 0);\n            this.Controls.SetChildIndex(this.CollapseHelpButton, 0);\n            this.Controls.SetChildIndex(this.SecurityCodeField, 0);\n            this.Controls.SetChildIndex(this.label3, 0);\n            this.Controls.SetChildIndex(this.ComputerNameField, 0);\n            this.Controls.SetChildIndex(this.LinkButton, 0);\n            this.Controls.SetChildIndex(this.HelpLabel, 0);\n            ((System.ComponentModel.ISupportInitialize)(this.LinkButton)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label label6;\n        private ColorBorderField SecurityCodeField;\n        private ColorBorderField ComputerNameField;\n        private System.Windows.Forms.Label label3;\n        private ImageButton LinkButton;\n        private System.Windows.Forms.Label label2;\n        private ImageButton ExpandHelpButton;\n        private ImageButton CollapseHelpButton;\n        private System.Windows.Forms.Label HelpLabel;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2aa.Designer.cs",
    "content": "using System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    partial class SetupPage2aa\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.label1 = new System.Windows.Forms.Label();\n            this.label6 = new System.Windows.Forms.Label();\n            this.label2 = new System.Windows.Forms.Label();\n            this.panel1 = new System.Windows.Forms.Panel();\n            this.SuspendLayout();\n            // \n            // label1\n            // \n            this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label1.ForeColor = System.Drawing.Color.White;\n            this.label1.Location = new System.Drawing.Point(49, 30);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(356, 150);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"ֻһӣ\";\n            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // label6\n            // \n            this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.label6.Location = new System.Drawing.Point(98, 185);\n            this.label6.Name = \"label6\";\n            this.label6.Size = new System.Drawing.Size(130, 18);\n            this.label6.TabIndex = 7;\n            this.label6.Text = \"\";\n            this.label6.TextAlign = System.Drawing.ContentAlignment.BottomLeft;\n            // \n            // label2\n            // \n            this.label2.AutoSize = true;\n            this.label2.BackColor = System.Drawing.Color.Transparent;\n            this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label2.ForeColor = System.Drawing.Color.White;\n            this.label2.Location = new System.Drawing.Point(213, 185);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(128, 16);\n            this.label2.TabIndex = 23;\n            this.label2.Text = \"ȥ룿\";\n            // \n            // panel1\n            // \n            this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel1.BackColor = System.Drawing.Color.White;\n            this.panel1.Location = new System.Drawing.Point(41, 170);\n            this.panel1.Name = \"panel1\";\n            this.panel1.Size = new System.Drawing.Size(370, 1);\n            this.panel1.TabIndex = 1;\n            // \n            // SetupPage2aa\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.panel1);\n            this.Controls.Add(this.label1);\n            this.Name = \"SetupPage2aa\";\n            this.Controls.SetChildIndex(this.label1, 0);\n            this.Controls.SetChildIndex(this.panel1, 0);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Label label6;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.Panel panel1;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2ab.Designer.cs",
    "content": "using System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    partial class SetupPage2ab\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.label1 = new System.Windows.Forms.Label();\n            this.label6 = new System.Windows.Forms.Label();\n            this.label4 = new System.Windows.Forms.Label();\n            this.label2 = new System.Windows.Forms.Label();\n            this.ExpandHelpButton = new MouseWithoutBorders.ImageButton();\n            this.CollapseHelpButton = new MouseWithoutBorders.ImageButton();\n            this.panel1 = new System.Windows.Forms.Panel();\n            this.panel2 = new System.Windows.Forms.Panel();\n            ((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).BeginInit();\n            this.SuspendLayout();\n            // \n            // label1\n            // \n            this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label1.ForeColor = System.Drawing.Color.White;\n            this.label1.Location = new System.Drawing.Point(49, 30);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(356, 53);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"Ǹ\";\n            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // label6\n            // \n            this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.label6.Location = new System.Drawing.Point(98, 208);\n            this.label6.Name = \"label6\";\n            this.label6.Size = new System.Drawing.Size(130, 18);\n            this.label6.TabIndex = 7;\n            this.label6.Text = \"\";\n            this.label6.TextAlign = System.Drawing.ContentAlignment.BottomLeft;\n            // \n            // label4\n            // \n            this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label4.ForeColor = System.Drawing.Color.White;\n            this.label4.Location = new System.Drawing.Point(61, 95);\n            this.label4.Name = \"label4\";\n            this.label4.Size = new System.Drawing.Size(332, 79);\n            this.label4.TabIndex = 27;\n            this.label4.Text = \"ƺϱĵԡȷеԶͬһ£û豸\";\n            // \n            // label2\n            // \n            this.label2.AutoSize = true;\n            this.label2.BackColor = System.Drawing.Color.Transparent;\n            this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label2.ForeColor = System.Drawing.Color.White;\n            this.label2.Location = new System.Drawing.Point(213, 208);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(128, 16);\n            this.label2.TabIndex = 23;\n            this.label2.Text = \"ȥ룿\";\n            // \n            // ExpandHelpButton\n            // \n            this.ExpandHelpButton.DisabledImage = null;\n            this.ExpandHelpButton.DownImage = null;\n            this.ExpandHelpButton.HoverImage = null;\n            this.ExpandHelpButton.Location = new System.Drawing.Point(0, 0);\n            this.ExpandHelpButton.Name = \"ExpandHelpButton\";\n            this.ExpandHelpButton.NormalImage = null;\n            this.ExpandHelpButton.Size = new System.Drawing.Size(80, 78);\n            this.ExpandHelpButton.TabIndex = 0;\n            this.ExpandHelpButton.TabStop = false;\n            // \n            // CollapseHelpButton\n            // \n            this.CollapseHelpButton.DisabledImage = null;\n            this.CollapseHelpButton.DownImage = null;\n            this.CollapseHelpButton.HoverImage = null;\n            this.CollapseHelpButton.Location = new System.Drawing.Point(0, 0);\n            this.CollapseHelpButton.Name = \"CollapseHelpButton\";\n            this.CollapseHelpButton.NormalImage = null;\n            this.CollapseHelpButton.Size = new System.Drawing.Size(80, 78);\n            this.CollapseHelpButton.TabIndex = 0;\n            this.CollapseHelpButton.TabStop = false;\n            // \n            // panel1\n            // \n            this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel1.BackColor = System.Drawing.Color.White;\n            this.panel1.Location = new System.Drawing.Point(41, 80);\n            this.panel1.Name = \"panel1\";\n            this.panel1.Size = new System.Drawing.Size(370, 1);\n            this.panel1.TabIndex = 1;\n            // \n            // panel2\n            // \n            this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel2.BackColor = System.Drawing.Color.White;\n            this.panel2.Location = new System.Drawing.Point(41, 170);\n            this.panel2.Name = \"panel2\";\n            this.panel2.Size = new System.Drawing.Size(370, 1);\n            this.panel2.TabIndex = 28;\n            // \n            // SetupPage2ab\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.panel2);\n            this.Controls.Add(this.label4);\n            this.Controls.Add(this.panel1);\n            this.Controls.Add(this.label1);\n            this.Name = \"SetupPage2ab\";\n            this.Controls.SetChildIndex(this.label1, 0);\n            this.Controls.SetChildIndex(this.panel1, 0);\n            this.Controls.SetChildIndex(this.label4, 0);\n            this.Controls.SetChildIndex(this.panel2, 0);\n            ((System.ComponentModel.ISupportInitialize)(this.ExpandHelpButton)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.CollapseHelpButton)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Label label6;\n        private System.Windows.Forms.Label label2;\n        private ImageButton ExpandHelpButton;\n        private ImageButton CollapseHelpButton;\n        private System.Windows.Forms.Panel panel1;\n        private System.Windows.Forms.Label label4;\n        private System.Windows.Forms.Panel panel2;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage2b.Designer.cs",
    "content": "using System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    partial class SetupPage2b\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.panel1 = new System.Windows.Forms.Panel();\n            this.label1 = new System.Windows.Forms.Label();\n            this.panel2 = new System.Windows.Forms.Panel();\n            this.label2 = new System.Windows.Forms.Label();\n            this.SecurityCodeLabel = new System.Windows.Forms.Label();\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\n            this.label5 = new System.Windows.Forms.Label();\n            this.label6 = new System.Windows.Forms.Label();\n            this.label4 = new System.Windows.Forms.Label();\n            this.MachineNameLabel = new System.Windows.Forms.Label();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\n            this.SuspendLayout();\n            // \n            // panel1\n            // \n            this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel1.BackColor = System.Drawing.Color.White;\n            this.panel1.Location = new System.Drawing.Point(41, 326);\n            this.panel1.Name = \"panel1\";\n            this.panel1.Size = new System.Drawing.Size(370, 1);\n            this.panel1.TabIndex = 1;\n            // \n            // label1\n            // \n            this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 28F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label1.ForeColor = System.Drawing.Color.White;\n            this.label1.Location = new System.Drawing.Point(61, 28);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(330, 56);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"Ͼͺ...\";\n            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // panel2\n            // \n            this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel2.BackColor = System.Drawing.Color.White;\n            this.panel2.Location = new System.Drawing.Point(41, 87);\n            this.panel2.Name = \"panel2\";\n            this.panel2.Size = new System.Drawing.Size(370, 1);\n            this.panel2.TabIndex = 2;\n            // \n            // label2\n            // \n            this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label2.ForeColor = System.Drawing.Color.White;\n            this.label2.Location = new System.Drawing.Point(61, 103);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(338, 80);\n            this.label2.TabIndex = 3;\n            this.label2.Text = \"ֻϢ߿ڣȻڱĵϰװ޽꣬ʼ̳üɡ\";\n            // \n            // SecurityCodeLabel\n            // \n            this.SecurityCodeLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.SecurityCodeLabel.ForeColor = System.Drawing.Color.White;\n            this.SecurityCodeLabel.Location = new System.Drawing.Point(68, 207);\n            this.SecurityCodeLabel.Name = \"SecurityCodeLabel\";\n            this.SecurityCodeLabel.Size = new System.Drawing.Size(310, 40);\n            this.SecurityCodeLabel.TabIndex = 4;\n            this.SecurityCodeLabel.Text = \"IlIlIlIlIl\";\n            this.SecurityCodeLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // pictureBox1\n            // \n            this.pictureBox1.Image = global::MouseWithoutBorders.Properties.Images.Mouse;\n            this.pictureBox1.Location = new System.Drawing.Point(206, 365);\n            this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);\n            this.pictureBox1.Name = \"pictureBox1\";\n            this.pictureBox1.Size = new System.Drawing.Size(44, 35);\n            this.pictureBox1.TabIndex = 0;\n            this.pictureBox1.TabStop = false;\n            // \n            // label5\n            // \n            this.label5.Font = new System.Drawing.Font(Control.DefaultFont.Name, 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label5.ForeColor = System.Drawing.Color.White;\n            this.label5.Location = new System.Drawing.Point(61, 170);\n            this.label5.Name = \"label5\";\n            this.label5.Size = new System.Drawing.Size(310, 24);\n            this.label5.TabIndex = 6;\n            this.label5.Text = \"ȻǾú!\";\n            // \n            // label6\n            // \n            this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label6.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.label6.Location = new System.Drawing.Point(71, 199);\n            this.label6.Name = \"label6\";\n            this.label6.Size = new System.Drawing.Size(310, 15);\n            this.label6.TabIndex = 7;\n            this.label6.Text = \"\";\n            this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // label4\n            // \n            this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label4.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(77)))), ((int)(((byte)(208)))), ((int)(((byte)(238)))));\n            this.label4.Location = new System.Drawing.Point(71, 258);\n            this.label4.Name = \"label4\";\n            this.label4.Size = new System.Drawing.Size(310, 15);\n            this.label4.TabIndex = 9;\n            this.label4.Text = \"豸\";\n            this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // MachineNameLabel\n            // \n            this.MachineNameLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.MachineNameLabel.ForeColor = System.Drawing.Color.White;\n            this.MachineNameLabel.Location = new System.Drawing.Point(50, 266);\n            this.MachineNameLabel.Name = \"MachineNameLabel\";\n            this.MachineNameLabel.Size = new System.Drawing.Size(340, 40);\n            this.MachineNameLabel.TabIndex = 8;\n            this.MachineNameLabel.Text = \"Сĵ\";\n            this.MachineNameLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // SetupPage2b\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.label4);\n            this.Controls.Add(this.MachineNameLabel);\n            this.Controls.Add(this.label6);\n            this.Controls.Add(this.label5);\n            this.Controls.Add(this.SecurityCodeLabel);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.panel2);\n            this.Controls.Add(this.panel1);\n            this.Controls.Add(this.pictureBox1);\n            this.Controls.Add(this.label1);\n            this.DoubleBuffered = true;\n            this.Name = \"SetupPage2b\";\n            this.Size = new System.Drawing.Size(453, 438);\n            this.Controls.SetChildIndex(this.label1, 0);\n            this.Controls.SetChildIndex(this.pictureBox1, 0);\n            this.Controls.SetChildIndex(this.panel1, 0);\n            this.Controls.SetChildIndex(this.panel2, 0);\n            this.Controls.SetChildIndex(this.label2, 0);\n            this.Controls.SetChildIndex(this.SecurityCodeLabel, 0);\n            this.Controls.SetChildIndex(this.label5, 0);\n            this.Controls.SetChildIndex(this.label6, 0);\n            this.Controls.SetChildIndex(this.MachineNameLabel, 0);\n            this.Controls.SetChildIndex(this.label4, 0);\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.PictureBox pictureBox1;\n        private System.Windows.Forms.Panel panel1;\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Panel panel2;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.Label SecurityCodeLabel;\n        private System.Windows.Forms.Label label5;\n        private System.Windows.Forms.Label label6;\n        private System.Windows.Forms.Label label4;\n        private System.Windows.Forms.Label MachineNameLabel;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage3a.Designer.cs",
    "content": "using System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    partial class SetupPage3a\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.label1 = new System.Windows.Forms.Label();\n            this.panel2 = new System.Windows.Forms.Panel();\n            this.MessageLabel = new System.Windows.Forms.Label();\n            this.ExamplePicture = new System.Windows.Forms.PictureBox();\n            this.labelStatus = new System.Windows.Forms.Label();\n            ((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).BeginInit();\n            this.SuspendLayout();\n            // \n            // label1\n            // \n            this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label1.ForeColor = System.Drawing.Color.White;\n            this.label1.Location = new System.Drawing.Point(65, 56);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(330, 116);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"ӣܿͿ...\\r\\n\";\n            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // panel2\n            // \n            this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel2.BackColor = System.Drawing.Color.White;\n            this.panel2.Location = new System.Drawing.Point(41, 178);\n            this.panel2.Name = \"panel2\";\n            this.panel2.Size = new System.Drawing.Size(370, 1);\n            this.panel2.TabIndex = 2;\n            // \n            // MessageLabel\n            // \n            this.MessageLabel.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.MessageLabel.ForeColor = System.Drawing.Color.White;\n            this.MessageLabel.Location = new System.Drawing.Point(71, 197);\n            this.MessageLabel.Name = \"MessageLabel\";\n            this.MessageLabel.Size = new System.Drawing.Size(310, 24);\n            this.MessageLabel.TabIndex = 4;\n            this.MessageLabel.Text = \"Ըճ\";\n            this.MessageLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // ExamplePicture\n            // \n            this.ExamplePicture.Image = global::MouseWithoutBorders.Properties.Images.copy_paste_example;\n            this.ExamplePicture.Location = new System.Drawing.Point(101, 251);\n            this.ExamplePicture.Name = \"ExamplePicture\";\n            this.ExamplePicture.Size = new System.Drawing.Size(251, 79);\n            this.ExamplePicture.TabIndex = 7;\n            this.ExamplePicture.TabStop = false;\n            // \n            // labelStatus\n            // \n            this.labelStatus.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.labelStatus.Font = new System.Drawing.Font(Control.DefaultFont.Name, 10F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.labelStatus.ForeColor = System.Drawing.Color.White;\n            this.labelStatus.Location = new System.Drawing.Point(0, 418);\n            this.labelStatus.Name = \"labelStatus\";\n            this.labelStatus.Size = new System.Drawing.Size(453, 20);\n            this.labelStatus.TabIndex = 8;\n            this.labelStatus.Text = \"...\";\n            this.labelStatus.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // SetupPage3a\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.labelStatus);\n            this.Controls.Add(this.ExamplePicture);\n            this.Controls.Add(this.MessageLabel);\n            this.Controls.Add(this.panel2);\n            this.Controls.Add(this.label1);\n            this.DoubleBuffered = true;\n            this.Name = \"SetupPage3a\";\n            this.Size = new System.Drawing.Size(453, 438);\n            this.Controls.SetChildIndex(this.label1, 0);\n            this.Controls.SetChildIndex(this.panel2, 0);\n            this.Controls.SetChildIndex(this.MessageLabel, 0);\n            this.Controls.SetChildIndex(this.ExamplePicture, 0);\n            this.Controls.SetChildIndex(this.labelStatus, 0);\n            ((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Panel panel2;\n        private System.Windows.Forms.Label MessageLabel;\n        private System.Windows.Forms.PictureBox ExamplePicture;\n        private System.Windows.Forms.Label labelStatus;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage3a.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Windows.Forms;\n\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\nusing MouseWithoutBorders.Properties;\n\nnamespace MouseWithoutBorders\n{\n    public partial class SetupPage3a : SettingsFormPage\n    {\n        private readonly Image[] _frames = { Images.copy_paste_example, Images.drag_example, Images.keyboard_example };\n        private readonly string[] _messages =\n        {\n                                                  \"跨电脑复制粘贴\",\n                                                  \"跨电脑拖拽文件\",\n                                                  \"共享一套鼠标键盘\",\n        };\n\n        private readonly int[] _timing = { 1000, 1000, 2000 };\n#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager\n        private readonly System.Timers.Timer _animationTimer;\n#pragma warning restore CA2213\n        private bool connected;\n        private bool done;\n        private bool invalidKey;\n\n        private int _animationFrame;\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]\n        public bool ReturnToSettings { get; set; }\n\n        public SetupPage3a()\n        {\n            InitializeComponent();\n            _animationTimer = new System.Timers.Timer { Interval = 1000 };\n        }\n\n        private void ShowStatus(string status)\n        {\n            labelStatus.Text = status;\n            Logger.Log(status);\n        }\n\n        public override void OnPageClosing()\n        {\n            _animationTimer.Stop();\n            base.OnPageClosing();\n        }\n\n        protected override void OnLoad(EventArgs e)\n        {\n            base.OnLoad(e);\n            _animationTimer.Elapsed += AnimationTimerTick;\n\n            Common.GetMachineName();\n            invalidKey = false;\n\n            UpdateAnimation();\n            _animationTimer.Start();\n\n            SocketStuff.InvalidKeyFound = false;\n            SocketStuff.InvalidKeyFoundOnClientSocket = false;\n\n            ShowStatus($\"正在连接中...\");\n\n            Common.SwitchToMultipleMode(false, false);\n            Common.ReopenSockets(true);\n\n            int timeOut = 0;\n            TcpSk connectedClientSocket;\n\n            // Client sockets run in different threads.\n            while (timeOut < 10)\n            {\n                Common.MMSleep(1);\n\n                if ((connectedClientSocket = Common.GetConnectedClientSocket()) != null)\n                {\n                    ShowStatus($\"已连接本地 IP 地址: {connectedClientSocket.Address}.\");\n                    Common.UpdateMachineTimeAndID();\n\n                    Common.MMSleep(1);\n                    connected = true;\n                    return;\n                }\n                else if (SocketStuff.InvalidKeyFoundOnClientSocket)\n                {\n                    invalidKey = true;\n                    ShowStatus(\"状态: 密码无效.\");\n                    Common.MMSleep(3);\n                    break;\n                }\n\n                timeOut++;\n            }\n\n            done = true;\n        }\n\n        private void AnimationTimerTick(object sender, EventArgs e)\n        {\n            _ = Invoke(new MethodInvoker(UpdateAnimation));\n        }\n\n        private void UpdateAnimation()\n        {\n            if ((ModifierKeys & Keys.Control) != 0)\n            {\n                _animationTimer.Stop();\n                SendNextPage(new SetupPage2ab());\n                return;\n            }\n\n            ExamplePicture.Image = _frames[_animationFrame];\n            MessageLabel.Text = _messages[_animationFrame];\n            _animationTimer.Interval = _timing[_animationFrame];\n            _animationFrame = (_animationFrame + 1) % _frames.Length;\n\n            if (connected)\n            {\n                _animationTimer.Stop();\n                SendNextPage(new SetupPage4());\n            }\n            else if (done)\n            {\n                _animationTimer.Stop();\n                SendNextPage(new SetupPage2ab());\n\n                if (invalidKey)\n                {\n                    Common.ShowToolTip(\n                        \"密码不正确。\\r\\n请检查是否在所有电脑上都输入了同一个密码。\\r\\n并检查您运行的是否都是同一版本的 \"\n                        + Application.ProductName + \"。\\r\\n本软件版本: \" + FrmAbout.AssemblyVersion,\n                        20000);\n                }\n                else\n                {\n                    string helpText = \"连接出错!\";\n                    helpText += \"\\r\\n请检查您的电脑是否连接到同一个网络，一般推荐插网线更稳定。\";\n                    helpText += \"\\r\\n再三检查 \" + Application.ProductName + \" 是不是被系统防火墙阻拦了。\";\n                    Common.ShowToolTip(helpText, 30000);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage4.Designer.cs",
    "content": "using System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    partial class SetupPage4\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.label1 = new System.Windows.Forms.Label();\n            this.panel2 = new System.Windows.Forms.Panel();\n            this.label5 = new System.Windows.Forms.Label();\n            this.ExamplePicture = new System.Windows.Forms.PictureBox();\n            this.label2 = new System.Windows.Forms.Label();\n            this.label3 = new System.Windows.Forms.Label();\n            this.panel1 = new System.Windows.Forms.Panel();\n            this.NextButton = new MouseWithoutBorders.ImageButton();\n            this.label4 = new System.Windows.Forms.Label();\n            this.label6 = new System.Windows.Forms.Label();\n            ((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.NextButton)).BeginInit();\n            this.SuspendLayout();\n            // \n            // label1\n            // \n            this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label1.ForeColor = System.Drawing.Color.White;\n            this.label1.Location = new System.Drawing.Point(65, 58);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(330, 52);\n            this.label1.TabIndex = 2;\n            this.label1.Text = \"ɹ\";\n            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // panel2\n            // \n            this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel2.BackColor = System.Drawing.Color.White;\n            this.panel2.Location = new System.Drawing.Point(41, 175);\n            this.panel2.Name = \"panel2\";\n            this.panel2.Size = new System.Drawing.Size(370, 1);\n            this.panel2.TabIndex = 2;\n            // \n            // label5\n            // \n            this.label5.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label5.ForeColor = System.Drawing.Color.White;\n            this.label5.Location = new System.Drawing.Point(57, 108);\n            this.label5.Name = \"label5\";\n            this.label5.Size = new System.Drawing.Size(344, 52);\n            this.label5.TabIndex = 6;\n            this.label5.Text = \"Ͳһ...\";\n            this.label5.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // ExamplePicture\n            // \n            this.ExamplePicture.Image = global::MouseWithoutBorders.Properties.Images.combined_example;\n            this.ExamplePicture.Location = new System.Drawing.Point(75, 283);\n            this.ExamplePicture.Name = \"ExamplePicture\";\n            this.ExamplePicture.Size = new System.Drawing.Size(307, 25);\n            this.ExamplePicture.TabIndex = 7;\n            this.ExamplePicture.TabStop = false;\n            // \n            // label2\n            // \n            this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label2.ForeColor = System.Drawing.Color.White;\n            this.label2.Location = new System.Drawing.Point(61, 200);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(310, 25);\n            this.label2.TabIndex = 8;\n            this.label2.Text = \"ͨ޽ʵЩ¡\";\n            // \n            // label3\n            // \n            this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label3.ForeColor = System.Drawing.Color.White;\n            this.label3.Location = new System.Drawing.Point(71, 242);\n            this.label3.Name = \"label3\";\n            this.label3.Size = new System.Drawing.Size(88, 38);\n            this.label3.TabIndex = 9;\n            this.label3.Text = \"Ըճ\";\n            this.label3.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // panel1\n            // \n            this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel1.BackColor = System.Drawing.Color.White;\n            this.panel1.Location = new System.Drawing.Point(41, 345);\n            this.panel1.Name = \"panel1\";\n            this.panel1.Size = new System.Drawing.Size(370, 1);\n            this.panel1.TabIndex = 3;\n            // \n            // NextButton\n            // \n            this.NextButton.DisabledImage = null;\n            this.NextButton.DownImage = global::MouseWithoutBorders.Properties.Images.next_button_click;\n            this.NextButton.HoverImage = global::MouseWithoutBorders.Properties.Images.next_button_hover;\n            this.NextButton.Image = global::MouseWithoutBorders.Properties.Images.next_button_normal;\n            this.NextButton.Location = new System.Drawing.Point(199, 366);\n            this.NextButton.Name = \"NextButton\";\n            this.NextButton.NormalImage = global::MouseWithoutBorders.Properties.Images.next_button_normal;\n            this.NextButton.Size = new System.Drawing.Size(55, 55);\n            this.NextButton.TabIndex = 16;\n            this.NextButton.TabStop = false;\n            this.NextButton.Click += new System.EventHandler(this.NextButtonClick);\n            // \n            // label4\n            // \n            this.label4.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label4.ForeColor = System.Drawing.Color.White;\n            this.label4.Location = new System.Drawing.Point(185, 242);\n            this.label4.Name = \"label4\";\n            this.label4.Size = new System.Drawing.Size(88, 38);\n            this.label4.TabIndex = 17;\n            this.label4.Text = \"קļ\";\n            this.label4.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // label6\n            // \n            this.label6.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label6.ForeColor = System.Drawing.Color.White;\n            this.label6.Location = new System.Drawing.Point(294, 242);\n            this.label6.Name = \"label6\";\n            this.label6.Size = new System.Drawing.Size(97, 38);\n            this.label6.TabIndex = 18;\n            this.label6.Text = \"һ׼\";\n            this.label6.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // SetupPage4\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.label6);\n            this.Controls.Add(this.label4);\n            this.Controls.Add(this.NextButton);\n            this.Controls.Add(this.panel1);\n            this.Controls.Add(this.label3);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.ExamplePicture);\n            this.Controls.Add(this.label5);\n            this.Controls.Add(this.panel2);\n            this.Controls.Add(this.label1);\n            this.DoubleBuffered = true;\n            this.Name = \"SetupPage4\";\n            this.Size = new System.Drawing.Size(453, 438);\n            this.Controls.SetChildIndex(this.label1, 0);\n            this.Controls.SetChildIndex(this.panel2, 0);\n            this.Controls.SetChildIndex(this.label5, 0);\n            this.Controls.SetChildIndex(this.ExamplePicture, 0);\n            this.Controls.SetChildIndex(this.label2, 0);\n            this.Controls.SetChildIndex(this.label3, 0);\n            this.Controls.SetChildIndex(this.panel1, 0);\n            this.Controls.SetChildIndex(this.NextButton, 0);\n            this.Controls.SetChildIndex(this.label4, 0);\n            this.Controls.SetChildIndex(this.label6, 0);\n            ((System.ComponentModel.ISupportInitialize)(this.ExamplePicture)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.NextButton)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Panel panel2;\n        private System.Windows.Forms.Label label5;\n        private System.Windows.Forms.PictureBox ExamplePicture;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.Label label3;\n        private System.Windows.Forms.Panel panel1;\n        private ImageButton NextButton;\n        private System.Windows.Forms.Label label4;\n        private System.Windows.Forms.Label label6;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/Settings/SetupPage5.Designer.cs",
    "content": "using System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    partial class SetupPage5\n    {\n        /// <summary> \n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary> \n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Component Designer generated code\n\n        /// <summary> \n        /// Required method for Designer support - do not modify \n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.pictureBox1 = new System.Windows.Forms.PictureBox();\n            this.label3 = new System.Windows.Forms.Label();\n            this.panel1 = new System.Windows.Forms.Panel();\n            this.label2 = new System.Windows.Forms.Label();\n            this.panel2 = new System.Windows.Forms.Panel();\n            this.label1 = new System.Windows.Forms.Label();\n            this.DoneButton = new MouseWithoutBorders.ImageButton();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();\n            ((System.ComponentModel.ISupportInitialize)(this.DoneButton)).BeginInit();\n            this.SuspendLayout();\n            // \n            // pictureBox1\n            // \n            this.pictureBox1.Image = global::MouseWithoutBorders.Properties.Images.Mouse;\n            this.pictureBox1.Location = new System.Drawing.Point(206, 40);\n            this.pictureBox1.Margin = new System.Windows.Forms.Padding(0);\n            this.pictureBox1.Name = \"pictureBox1\";\n            this.pictureBox1.Size = new System.Drawing.Size(41, 36);\n            this.pictureBox1.TabIndex = 25;\n            this.pictureBox1.TabStop = false;\n            // \n            // label3\n            // \n            this.label3.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Bold);\n            this.label3.ForeColor = System.Drawing.Color.White;\n            this.label3.Location = new System.Drawing.Point(61, 271);\n            this.label3.Name = \"label3\";\n            this.label3.Size = new System.Drawing.Size(310, 25);\n            this.label3.TabIndex = 24;\n            this.label3.Text = \"ףÿģ\";\n            // \n            // panel1\n            // \n            this.panel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel1.BackColor = System.Drawing.Color.White;\n            this.panel1.Location = new System.Drawing.Point(41, 96);\n            this.panel1.Name = \"panel1\";\n            this.panel1.Size = new System.Drawing.Size(370, 1);\n            this.panel1.TabIndex = 20;\n            // \n            // label2\n            // \n            this.label2.Font = new System.Drawing.Font(Control.DefaultFont.Name, 9.75F);\n            this.label2.ForeColor = System.Drawing.Color.White;\n            this.label2.Location = new System.Drawing.Point(61, 226);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(310, 40);\n            this.label2.TabIndex = 22;\n            this.label2.Text = \"ʱͨͼá\";\n            // \n            // panel2\n            // \n            this.panel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)\n                        | System.Windows.Forms.AnchorStyles.Right)));\n            this.panel2.BackColor = System.Drawing.Color.White;\n            this.panel2.Location = new System.Drawing.Point(41, 208);\n            this.panel2.Name = \"panel2\";\n            this.panel2.Size = new System.Drawing.Size(370, 1);\n            this.panel2.TabIndex = 18;\n            // \n            // label1\n            // \n            this.label1.Font = new System.Drawing.Font(Control.DefaultFont.Name, 30F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.label1.ForeColor = System.Drawing.Color.White;\n            this.label1.Location = new System.Drawing.Point(62, 99);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(330, 109);\n            this.label1.TabIndex = 19;\n            this.label1.Text = \"ɡ\\r\\nɵƯ\";\n            this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;\n            // \n            // DoneButton\n            // \n            this.DoneButton.DisabledImage = null;\n            this.DoneButton.DownImage = global::MouseWithoutBorders.Properties.Images.done_button_click;\n            this.DoneButton.HoverImage = global::MouseWithoutBorders.Properties.Images.done_button_hover;\n            this.DoneButton.Image = global::MouseWithoutBorders.Properties.Images.done_button_normal;\n            this.DoneButton.Location = new System.Drawing.Point(199, 366);\n            this.DoneButton.Name = \"DoneButton\";\n            this.DoneButton.NormalImage = global::MouseWithoutBorders.Properties.Images.done_button_normal;\n            this.DoneButton.Size = new System.Drawing.Size(55, 56);\n            this.DoneButton.TabIndex = 26;\n            this.DoneButton.TabStop = false;\n            this.DoneButton.Click += new System.EventHandler(this.DoneButtonClick);\n            // \n            // SetupPage5\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.DodgerBlue;\n            this.Controls.Add(this.DoneButton);\n            this.Controls.Add(this.panel1);\n            this.Controls.Add(this.label1);\n            this.Controls.Add(this.pictureBox1);\n            this.Controls.Add(this.label3);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.panel2);\n            this.DoubleBuffered = true;\n            this.Name = \"SetupPage5\";\n            this.Size = new System.Drawing.Size(453, 438);\n            this.Controls.SetChildIndex(this.panel2, 0);\n            this.Controls.SetChildIndex(this.label2, 0);\n            this.Controls.SetChildIndex(this.label3, 0);\n            this.Controls.SetChildIndex(this.pictureBox1, 0);\n            this.Controls.SetChildIndex(this.label1, 0);\n            this.Controls.SetChildIndex(this.panel1, 0);\n            this.Controls.SetChildIndex(this.DoneButton, 0);\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();\n            ((System.ComponentModel.ISupportInitialize)(this.DoneButton)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.PictureBox pictureBox1;\n        private System.Windows.Forms.Label label3;\n        private System.Windows.Forms.Panel panel1;\n        private System.Windows.Forms.Label label2;\n        private System.Windows.Forms.Panel panel2;\n        private System.Windows.Forms.Label label1;\n        private ImageButton DoneButton;\n\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmAbout.Designer.cs",
    "content": "﻿namespace MouseWithoutBorders\n{\n    partial class FrmAbout\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmAbout));\n            this.logoPictureBox = new System.Windows.Forms.PictureBox();\n            this.labelProductName = new System.Windows.Forms.Label();\n            this.labelCopyright = new System.Windows.Forms.Label();\n            this.labelCompanyName = new System.Windows.Forms.Label();\n            this.groupBoxContributors = new System.Windows.Forms.GroupBox();\n            this.textBoxContributors = new System.Windows.Forms.TextBox();\n            this.okButton = new System.Windows.Forms.Button();\n            ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).BeginInit();\n            this.groupBoxContributors.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // logoPictureBox\n            // \n            this.logoPictureBox.ErrorImage = null;\n            this.logoPictureBox.Image = global::MouseWithoutBorders.Properties.Images.Logo;\n            this.logoPictureBox.Location = new System.Drawing.Point(12, 12);\n            this.logoPictureBox.Name = \"logoPictureBox\";\n            this.logoPictureBox.Size = new System.Drawing.Size(131, 136);\n            this.logoPictureBox.SizeMode = System.Windows.Forms.PictureBoxSizeMode.StretchImage;\n            this.logoPictureBox.TabIndex = 12;\n            this.logoPictureBox.TabStop = false;\n            // \n            // labelProductName\n            // \n            this.labelProductName.AutoSize = true;\n            this.labelProductName.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.labelProductName.Location = new System.Drawing.Point(152, 12);\n            this.labelProductName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);\n            this.labelProductName.MaximumSize = new System.Drawing.Size(0, 17);\n            this.labelProductName.Name = \"labelProductName\";\n            this.labelProductName.Size = new System.Drawing.Size(87, 13);\n            this.labelProductName.TabIndex = 27;\n            this.labelProductName.Text = \"Product Name\";\n            this.labelProductName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;\n            // \n            // labelCopyright\n            // \n            this.labelCopyright.AutoSize = true;\n            this.labelCopyright.Location = new System.Drawing.Point(152, 31);\n            this.labelCopyright.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);\n            this.labelCopyright.MaximumSize = new System.Drawing.Size(0, 17);\n            this.labelCopyright.Name = \"labelCopyright\";\n            this.labelCopyright.Size = new System.Drawing.Size(51, 13);\n            this.labelCopyright.TabIndex = 28;\n            this.labelCopyright.Text = \"Copyright\";\n            this.labelCopyright.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;\n            // \n            // labelCompanyName\n            // \n            this.labelCompanyName.AutoSize = true;\n            this.labelCompanyName.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.labelCompanyName.Location = new System.Drawing.Point(9, 162);\n            this.labelCompanyName.Margin = new System.Windows.Forms.Padding(6, 0, 3, 0);\n            this.labelCompanyName.MaximumSize = new System.Drawing.Size(0, 17);\n            this.labelCompanyName.Name = \"labelCompanyName\";\n            this.labelCompanyName.Size = new System.Drawing.Size(94, 13);\n            this.labelCompanyName.TabIndex = 29;\n            this.labelCompanyName.Text = \"Company Name\";\n            this.labelCompanyName.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;\n            // \n            // groupBoxContributors\n            // \n            this.groupBoxContributors.Controls.Add(this.textBoxContributors);\n            this.groupBoxContributors.Location = new System.Drawing.Point(12, 178);\n            this.groupBoxContributors.Name = \"groupBoxContributors\";\n            this.groupBoxContributors.Size = new System.Drawing.Size(466, 350);\n            this.groupBoxContributors.TabIndex = 30;\n            this.groupBoxContributors.TabStop = false;\n            this.groupBoxContributors.Text = \" 贡献者 \";\n            // \n            // textBoxContributors\n            // \n            this.textBoxContributors.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.textBoxContributors.Location = new System.Drawing.Point(3, 16);\n            this.textBoxContributors.Multiline = true;\n            this.textBoxContributors.Name = \"textBoxContributors\";\n            this.textBoxContributors.ReadOnly = true;\n            this.textBoxContributors.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;\n            this.textBoxContributors.Size = new System.Drawing.Size(460, 331);\n            this.textBoxContributors.TabIndex = 31;\n            // \n            // okButton\n            // \n            this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));\n            this.okButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.okButton.Location = new System.Drawing.Point(403, 534);\n            this.okButton.Name = \"okButton\";\n            this.okButton.Size = new System.Drawing.Size(75, 23);\n            this.okButton.TabIndex = 24;\n            this.okButton.Text = \"确定\";\n            // \n            // frmAbout\n            // \n            this.AcceptButton = this.okButton;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;\n            this.ClientSize = new System.Drawing.Size(487, 561);\n            this.Controls.Add(this.okButton);\n            this.Controls.Add(this.logoPictureBox);\n            this.Controls.Add(this.labelProductName);\n            this.Controls.Add(this.labelCopyright);\n            this.Controls.Add(this.labelCompanyName);\n            this.Controls.Add(this.groupBoxContributors);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"frmAbout\";\n            this.Opacity = 0.9D;\n            this.Padding = new System.Windows.Forms.Padding(9);\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"frmAbout\";\n            this.TopMost = true;\n            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FrmAbout_FormClosed);\n            ((System.ComponentModel.ISupportInitialize)(this.logoPictureBox)).EndInit();\n            this.groupBoxContributors.ResumeLayout(false);\n            this.groupBoxContributors.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.PictureBox logoPictureBox;\n        private System.Windows.Forms.Label labelProductName;\n        private System.Windows.Forms.Label labelCopyright;\n        private System.Windows.Forms.Label labelCompanyName;\n        private System.Windows.Forms.GroupBox groupBoxContributors;\n        private System.Windows.Forms.Button okButton;\n        private System.Windows.Forms.TextBox textBoxContributors;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmAbout.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\n// <summary>\n//     About box.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing System;\nusing System.Globalization;\nusing System.Reflection;\nusing System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    internal partial class FrmAbout : System.Windows.Forms.Form, IDisposable\n    {\n        internal FrmAbout()\n        {\n            InitializeComponent();\n            Text = string.Format(CultureInfo.CurrentCulture, \"关于 {0}\", AssemblyTitle);\n            labelProductName.Text = string.Format(CultureInfo.CurrentCulture, \"{0} {1}\", AssemblyProduct, AssemblyVersion);\n            labelCopyright.Text = AssemblyCopyright;\n            labelCompanyName.Text = \"项目创建者: Truong Do (Đỗ Đức Trường)\";\n\n            textBoxContributors.Text += \"* 微软车库: Quinn Hawkins, Michael Low, Joe Coplen, Nino Yuniardi, Gwyneth Marshall, David Andrews, Karen Luecking\";\n            textBoxContributors.Text += \"\\r\\n* Peter Hauge\\t\\t- Visual Studio\";\n            textBoxContributors.Text += \"\\r\\n* Bruce Dawson\\t\\t- Windows Fundamentals\";\n            textBoxContributors.Text += \"\\r\\n* Alan Myrvold\\t\\t- Office Security\";\n            textBoxContributors.Text += \"\\r\\n* Adrian Garside\\t\\t- WEX\";\n            textBoxContributors.Text += \"\\r\\n* Scott Bradner\\t\\t- Surface\";\n            textBoxContributors.Text += \"\\r\\n* Aleks Gershaft\\t\\t- Windows Azure\";\n            textBoxContributors.Text += \"\\r\\n* Chinh Huynh\\t\\t- Windows Azure\";\n            textBoxContributors.Text += \"\\r\\n* Long Nguyen\\t\\t- Data Center\";\n            textBoxContributors.Text += \"\\r\\n* Triet Le\\t\\t\\t- Cloud Engineering\";\n            textBoxContributors.Text += \"\\r\\n* Luke Schoen\\t\\t- Excel\";\n            textBoxContributors.Text += \"\\r\\n* Bao Nguyen\\t\\t- Bing\";\n            textBoxContributors.Text += \"\\r\\n* Ross Nichols\\t\\t- Windows\";\n            textBoxContributors.Text += \"\\r\\n* Ryan Baltazar\\t\\t- Windows\";\n            textBoxContributors.Text += \"\\r\\n* Ed Essey\\t\\t\\t- The Garage\";\n            textBoxContributors.Text += \"\\r\\n* Mario Madden\\t\\t- The Garage\";\n            textBoxContributors.Text += \"\\r\\n* Karthick Mahalingam\\t- ACE\";\n            textBoxContributors.Text += \"\\r\\n* Pooja Kamra\\t\\t- ACE\";\n            textBoxContributors.Text += \"\\r\\n* Justin White\\t\\t- SA\";\n            textBoxContributors.Text += \"\\r\\n* Chris Ransom\\t\\t- SA\";\n            textBoxContributors.Text += \"\\r\\n* Mike Ricks\\t\\t- Red Team\";\n            textBoxContributors.Text += \"\\r\\n* Randy Santossio\\t\\t- Surface\";\n            textBoxContributors.Text += \"\\r\\n* Ashish Sen Jaswal\\t\\t- Device Health\";\n            textBoxContributors.Text += \"\\r\\n* Zoltan Harmath\\t\\t- Security Tools\";\n            textBoxContributors.Text += \"\\r\\n* Luciano Krigun\\t\\t- Security Products\";\n            textBoxContributors.Text += \"\\r\\n* Jo Hemmerlein\\t\\t- Red Team\";\n            textBoxContributors.Text += \"\\r\\n* Chris Johnson\\t\\t- Surface Hub\";\n            textBoxContributors.Text += \"\\r\\n* Loren Ponten\\t\\t- Surface Hub\";\n            textBoxContributors.Text += \"\\r\\n* Paul Schmitt\\t\\t- WWL\";\n\n            textBoxContributors.Text += \"\\r\\n\\r\\n* 还有我们的众多用户！\";\n        }\n\n        internal static string AssemblyTitle\n        {\n            get\n            {\n                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyTitleAttribute), false);\n                if (attributes.Length > 0)\n                {\n                    AssemblyTitleAttribute titleAttribute = (AssemblyTitleAttribute)attributes[0];\n                    if (titleAttribute.Title != null && titleAttribute.Title.Length > 0)\n                    {\n                        return titleAttribute.Title;\n                    }\n                }\n\n                return System.IO.Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location);\n            }\n        }\n\n        internal static string AssemblyVersion => Assembly.GetExecutingAssembly().GetName().Version.ToString();\n\n        internal static string AssemblyDescription\n        {\n            get\n            {\n                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyDescriptionAttribute), false);\n                return attributes.Length == 0 ? string.Empty : ((AssemblyDescriptionAttribute)attributes[0]).Description;\n            }\n        }\n\n        internal static string AssemblyProduct\n        {\n            get\n            {\n                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyProductAttribute), false);\n                return attributes.Length == 0 ? string.Empty : ((AssemblyProductAttribute)attributes[0]).Product;\n            }\n        }\n\n        internal static string AssemblyCopyright\n        {\n            get\n            {\n                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCopyrightAttribute), false);\n                return attributes.Length == 0 ? string.Empty : ((AssemblyCopyrightAttribute)attributes[0]).Copyright;\n            }\n        }\n\n        internal static string AssemblyCompany\n        {\n            get\n            {\n                object[] attributes = Assembly.GetExecutingAssembly().GetCustomAttributes(typeof(AssemblyCompanyAttribute), false);\n                return attributes.Length == 0 ? string.Empty : ((AssemblyCompanyAttribute)attributes[0]).Company;\n            }\n        }\n\n        private void FrmAbout_FormClosed(object sender, FormClosedEventArgs e)\n        {\n            Common.AboutForm = null;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmInputCallback.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.ComponentModel;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Windows.Forms;\n\n// <summary>\n//     Keyboard/Mouse hook callbacks are handled in the message loop of this form.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\n\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1300:SpecifyMessageBoxOptions\", Scope = \"member\", Target = \"MouseWithoutBorders.frmInputCallback.#InstallKeyboardAndMouseHook()\", Justification = \"Dotnet port with style preservation\")]\n\nnamespace MouseWithoutBorders\n{\n    internal partial class FrmInputCallback : System.Windows.Forms.Form\n    {\n        internal FrmInputCallback()\n        {\n            InitializeComponent();\n        }\n\n        private void FrmInputCallback_Load(object sender, EventArgs e)\n        {\n            InstallKeyboardAndMouseHook();\n            Left = 0;\n            Top = 0;\n            Width = 0;\n            Height = 0;\n        }\n\n        private void FrmInputCallback_Shown(object sender, EventArgs e)\n        {\n            Common.InputCallbackForm = this;\n            Visible = false;\n        }\n\n        private void FrmInputCallback_FormClosing(object sender, FormClosingEventArgs e)\n        {\n            if (e.CloseReason != CloseReason.WindowsShutDown)\n            {\n                // e.Cancel = true;\n            }\n        }\n\n        internal void InstallKeyboardAndMouseHook()\n        {\n            /*\n             * Install hooks:\n             * According to http://msdn.microsoft.com/en-us/library/ms644986(VS.85).aspx\n             * we need to process the hook callback message fast enough so make the message loop thread a\n             * high priority thread. (Mouse/Keyboard event is important)\n             * */\n            try\n            {\n                Common.Hook = new InputHook();\n                Common.Hook.MouseEvent += new InputHook.MouseEvHandler(Common.MouseEvent);\n                Common.Hook.KeyboardEvent += new InputHook.KeybdEvHandler(Common.KeybdEvent);\n\n                Logger.Log(\"(((((Keyboard/Mouse hooks installed/reinstalled!)))))\");\n                /* The hook is called in the context of the thread that installed it.\n                 * The call is made by sending a message to the thread that installed the hook.\n                 * Therefore, the thread that installed the hook must have a message loop!!!\n                 * */\n            }\n            catch (Win32Exception e)\n            {\n                _ = MessageBox.Show(\n                    \"安装鼠标/键盘侦听器失败，错误代码: \" + e.ErrorCode,\n                    Application.ProductName,\n                    MessageBoxButtons.OK,\n                    MessageBoxIcon.Error);\n                Common.MainForm.Quit(false, false); // we are [STAThread] :)\n            }\n\n            // Thread.CurrentThread.Priority = ThreadPriority.Highest;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmLogon.Designer.cs",
    "content": "﻿namespace MouseWithoutBorders\n{\n    partial class frmLogon\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(frmLogon));\n            this.labelDesktop = new System.Windows.Forms.Label();\n            this.SuspendLayout();\n            // \n            // labelDesktop\n            // \n            this.labelDesktop.AutoSize = true;\n            this.labelDesktop.BackColor = System.Drawing.Color.White;\n            this.labelDesktop.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;\n            this.labelDesktop.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.labelDesktop.ForeColor = System.Drawing.Color.LimeGreen;\n            this.labelDesktop.Location = new System.Drawing.Point(1, 1);\n            this.labelDesktop.Name = \"labelDesktop\";\n            this.labelDesktop.Size = new System.Drawing.Size(80, 15);\n            this.labelDesktop.TabIndex = 0;\n            this.labelDesktop.Text = \"微软无界鼠标\";\n            // \n            // frmLogon\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(83, 17);\n            this.ControlBox = false;\n            this.Controls.Add(this.labelDesktop);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"frmLogon\";\n            this.Opacity = 0.5;\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.Text = \"微软无界鼠标\";\n            this.TopMost = true;\n            this.Load += new System.EventHandler(this.frmLogon_Load);\n            this.Shown += new System.EventHandler(this.frmLogon_Shown);\n            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.frmLogon_FormClosing);\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label labelDesktop;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMatrix.Designer.cs",
    "content": "﻿using System.Windows.Forms;\nusing System.Collections.Generic;\nusing System.Drawing;\nusing Windows.UI.Notifications;\n\nnamespace MouseWithoutBorders\n{\n    partial class FrmMatrix\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMatrix));\n            this.pictureBoxMouseWithoutBorders0 = new System.Windows.Forms.PictureBox();\n            this.toolTip = new System.Windows.Forms.ToolTip(this.components);\n            this.comboBoxLockMachine = new System.Windows.Forms.ComboBox();\n            this.comboBoxSwitchToAllPC = new System.Windows.Forms.ComboBox();\n            this.comboBoxReconnect = new System.Windows.Forms.ComboBox();\n            this.checkBoxTwoRow = new System.Windows.Forms.CheckBox();\n            this.comboBoxEasyMouse = new System.Windows.Forms.ComboBox();\n            this.checkBoxDrawMouse = new System.Windows.Forms.CheckBox();\n            this.checkBoxMouseMoveRelatively = new System.Windows.Forms.CheckBox();\n            this.checkBoxHideMouse = new System.Windows.Forms.CheckBox();\n            this.checkBoxBlockMouseAtCorners = new System.Windows.Forms.CheckBox();\n            this.checkBoxCircle = new System.Windows.Forms.CheckBox();\n            this.checkBoxBlockScreenSaver = new System.Windows.Forms.CheckBox();\n            this.checkBoxHideLogo = new System.Windows.Forms.CheckBox();\n            this.checkBoxShareClipboard = new System.Windows.Forms.CheckBox();\n            this.checkBoxDisableCAD = new System.Windows.Forms.CheckBox();\n            this.buttonOK = new System.Windows.Forms.Button();\n            this.checkBoxReverseLookup = new System.Windows.Forms.CheckBox();\n            this.checkBoxVKMap = new System.Windows.Forms.CheckBox();\n            this.comboBoxScreenCapture = new System.Windows.Forms.ComboBox();\n            this.checkBoxSameSubNet = new System.Windows.Forms.CheckBox();\n            this.checkBoxClipNetStatus = new System.Windows.Forms.CheckBox();\n            this.checkBoxSendLog = new System.Windows.Forms.CheckBox();\n            this.groupBoxKeySetup = new System.Windows.Forms.GroupBox();\n            this.buttonNewKey = new System.Windows.Forms.Button();\n            this.textBoxEnc = new System.Windows.Forms.TextBox();\n            this.LabelEnc = new System.Windows.Forms.Label();\n            this.checkBoxShowKey = new System.Windows.Forms.CheckBox();\n            this.labelEasyMouse = new System.Windows.Forms.Label();\n            this.comboBoxEasyMouseOption = new System.Windows.Forms.ComboBox();\n            this.checkBoxTransferFile = new System.Windows.Forms.CheckBox();\n            this.toolTipManual = new System.Windows.Forms.ToolTip(this.components);\n            this.tabPageOther = new System.Windows.Forms.TabPage();\n            this.groupBoxOtherOptions = new System.Windows.Forms.GroupBox();\n            this.groupBoxShortcuts = new System.Windows.Forms.GroupBox();\n            this.labelScreenCapture = new System.Windows.Forms.Label();\n            this.LabelToggleEasyMouse = new System.Windows.Forms.Label();\n            this.comboBoxExitMM = new System.Windows.Forms.ComboBox();\n            this.comboBoxShowSettings = new System.Windows.Forms.ComboBox();\n            this.labelReconnect = new System.Windows.Forms.Label();\n            this.labelSwitch2AllPCMode = new System.Windows.Forms.Label();\n            this.radioButtonDisable = new System.Windows.Forms.RadioButton();\n            this.radioButtonNum = new System.Windows.Forms.RadioButton();\n            this.radioButtonF1 = new System.Windows.Forms.RadioButton();\n            this.labelLockMachine = new System.Windows.Forms.Label();\n            this.labelExitMM = new System.Windows.Forms.Label();\n            this.labelShowSettings = new System.Windows.Forms.Label();\n            this.labelSwitchBetweenMachine = new System.Windows.Forms.Label();\n            this.tabPageMain = new System.Windows.Forms.TabPage();\n            this.buttonCancel = new System.Windows.Forms.Button();\n            this.groupBoxMachineMatrix = new System.Windows.Forms.GroupBox();\n            this.linkLabelReConfigure = new System.Windows.Forms.LinkLabel();\n            this.tabControlSetting = new System.Windows.Forms.TabControl();\n            this.tabPageAdvancedSettings = new System.Windows.Forms.TabPage();\n            this.groupBoxName2IPPolicyList = new System.Windows.Forms.GroupBox();\n            this.textBoxMachineName2IPPolicyList = new System.Windows.Forms.TextBox();\n            this.pictureBoxMouseWithoutBorders = new System.Windows.Forms.PictureBox();\n            this.groupBoxDNS = new System.Windows.Forms.GroupBox();\n            this.textBoxMachineName2IP = new System.Windows.Forms.TextBox();\n            this.textBoxDNS = new System.Windows.Forms.TextBox();\n            this.linkLabelHelp = new System.Windows.Forms.LinkLabel();\n            this.linkLabelMiniLog = new System.Windows.Forms.LinkLabel();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders0)).BeginInit();\n            this.groupBoxKeySetup.SuspendLayout();\n            this.tabPageOther.SuspendLayout();\n            this.groupBoxOtherOptions.SuspendLayout();\n            this.groupBoxShortcuts.SuspendLayout();\n            this.tabPageMain.SuspendLayout();\n            this.groupBoxMachineMatrix.SuspendLayout();\n            this.tabControlSetting.SuspendLayout();\n            this.tabPageAdvancedSettings.SuspendLayout();\n            this.groupBoxName2IPPolicyList.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders)).BeginInit();\n            this.groupBoxDNS.SuspendLayout();\n            this.SuspendLayout();\n            // \n            // pictureBoxMouseWithoutBorders0\n            // \n            this.pictureBoxMouseWithoutBorders0.BackgroundImage = ((System.Drawing.Image)(resources.GetObject(\"pictureBoxMouseWithoutBorders0.BackgroundImage\")));\n            this.pictureBoxMouseWithoutBorders0.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;\n            this.pictureBoxMouseWithoutBorders0.Location = new System.Drawing.Point(590, 271);\n            this.pictureBoxMouseWithoutBorders0.Name = \"pictureBoxMouseWithoutBorders0\";\n            this.pictureBoxMouseWithoutBorders0.Size = new System.Drawing.Size(190, 54);\n            this.pictureBoxMouseWithoutBorders0.TabIndex = 16;\n            this.pictureBoxMouseWithoutBorders0.TabStop = false;\n            this.pictureBoxMouseWithoutBorders0.Visible = false;\n            // \n            // toolTip\n            // \n            this.toolTip.AutomaticDelay = 100;\n            this.toolTip.AutoPopDelay = 5000;\n            this.toolTip.InitialDelay = 100;\n            this.toolTip.ReshowDelay = 20;\n            this.toolTip.ToolTipIcon = System.Windows.Forms.ToolTipIcon.Info;\n            this.toolTip.ToolTipTitle = \"Microsoft® Visual Studio® 2010\";\n            // \n            // comboBoxLockMachine\n            // \n            this.comboBoxLockMachine.Enabled = true;\n            this.comboBoxLockMachine.FormattingEnabled = true;\n            this.comboBoxLockMachine.Items.AddRange(new object[] {\n            \"A\",\n            \"B\",\n            \"C\",\n            \"D\",\n            \"E\",\n            \"F\",\n            \"G\",\n            \"H\",\n            \"I\",\n            \"J\",\n            \"K\",\n            \"L\",\n            \"M\",\n            \"N\",\n            \"O\",\n            \"P\",\n            \"Q\",\n            \"R\",\n            \"S\",\n            \"T\",\n            \"U\",\n            \"V\",\n            \"W\",\n            \"X\",\n            \"Y\",\n            \"Z\",\n            \"关闭\"});\n            this.comboBoxLockMachine.Location = new System.Drawing.Point(230, 68);\n            this.comboBoxLockMachine.Name = \"comboBoxLockMachine\";\n            this.comboBoxLockMachine.Size = new System.Drawing.Size(54, 21);\n            this.comboBoxLockMachine.TabIndex = 205;\n            this.comboBoxLockMachine.Text = \"L\";\n            this.toolTip.SetToolTip(this.comboBoxLockMachine, \"双击锁定所有电脑。\");\n            this.comboBoxLockMachine.TextChanged += new System.EventHandler(this.ComboBoxLockMachine_TextChanged);\n            // \n            // comboBoxSwitchToAllPC\n            // \n            this.comboBoxSwitchToAllPC.Enabled = true;\n            this.comboBoxSwitchToAllPC.FormattingEnabled = true;\n            this.comboBoxSwitchToAllPC.Items.AddRange(new object[] {\n            \"Ctrl*3\",\n            \"A\",\n            \"B\",\n            \"C\",\n            \"D\",\n            \"E\",\n            \"F\",\n            \"G\",\n            \"H\",\n            \"I\",\n            \"J\",\n            \"K\",\n            \"L\",\n            \"M\",\n            \"N\",\n            \"O\",\n            \"P\",\n            \"Q\",\n            \"R\",\n            \"S\",\n            \"T\",\n            \"U\",\n            \"V\",\n            \"W\",\n            \"X\",\n            \"Y\",\n            \"Z\",\n            \"关闭\"});\n            this.comboBoxSwitchToAllPC.Location = new System.Drawing.Point(490, 68);\n            this.comboBoxSwitchToAllPC.Name = \"comboBoxSwitchToAllPC\";\n            this.comboBoxSwitchToAllPC.Size = new System.Drawing.Size(56, 21);\n            this.comboBoxSwitchToAllPC.TabIndex = 206;\n            this.comboBoxSwitchToAllPC.Text = \"关闭\";\n            this.toolTip.SetToolTip(this.comboBoxSwitchToAllPC, \"按三次 Ctrl 或者 Ctrl+Alt+[?]\");\n            this.comboBoxSwitchToAllPC.TextChanged += new System.EventHandler(this.ComboBoxSwitchToAllPC_TextChanged);\n            // \n            // comboBoxReconnect\n            // \n            this.comboBoxReconnect.Enabled = true;\n            this.comboBoxReconnect.FormattingEnabled = true;\n            this.comboBoxReconnect.Items.AddRange(new object[] {\n            \"A\",\n            \"B\",\n            \"C\",\n            \"D\",\n            \"E\",\n            \"F\",\n            \"G\",\n            \"H\",\n            \"I\",\n            \"J\",\n            \"K\",\n            \"L\",\n            \"M\",\n            \"N\",\n            \"O\",\n            \"P\",\n            \"Q\",\n            \"R\",\n            \"S\",\n            \"T\",\n            \"U\",\n            \"V\",\n            \"W\",\n            \"X\",\n            \"Y\",\n            \"Z\",\n            \"关闭\"});\n            this.comboBoxReconnect.Location = new System.Drawing.Point(230, 95);\n            this.comboBoxReconnect.Name = \"comboBoxReconnect\";\n            this.comboBoxReconnect.Size = new System.Drawing.Size(54, 21);\n            this.comboBoxReconnect.TabIndex = 207;\n            this.comboBoxReconnect.Text = \"R\";\n            this.toolTip.SetToolTip(this.comboBoxReconnect, \"防止连接丢失。\");\n            this.comboBoxReconnect.TextChanged += new System.EventHandler(this.ComboBoxReconnect_TextChanged);\n            // \n            // checkBoxTwoRow\n            // \n            this.checkBoxTwoRow.AutoSize = true;\n            this.checkBoxTwoRow.Location = new System.Drawing.Point(9, 205);\n            this.checkBoxTwoRow.Name = \"checkBoxTwoRow\";\n            this.checkBoxTwoRow.Size = new System.Drawing.Size(72, 17);\n            this.checkBoxTwoRow.TabIndex = 6;\n            this.checkBoxTwoRow.Text = \"双行排列(&R)\";\n            this.toolTip.SetToolTip(this.checkBoxTwoRow, \"选中改为上下两行，可上下移动鼠标来切换设备。\");\n            this.checkBoxTwoRow.UseVisualStyleBackColor = true;\n            this.checkBoxTwoRow.CheckedChanged += new System.EventHandler(this.CheckBoxTwoRow_CheckedChanged);\n            // \n            // comboBoxEasyMouse\n            // \n            this.comboBoxEasyMouse.Enabled = true;\n            this.comboBoxEasyMouse.FormattingEnabled = true;\n            this.comboBoxEasyMouse.Items.AddRange(new object[] {\n            \"A\",\n            \"B\",\n            \"C\",\n            \"D\",\n            \"E\",\n            \"F\",\n            \"G\",\n            \"H\",\n            \"I\",\n            \"J\",\n            \"K\",\n            \"L\",\n            \"M\",\n            \"N\",\n            \"O\",\n            \"P\",\n            \"Q\",\n            \"R\",\n            \"S\",\n            \"T\",\n            \"U\",\n            \"V\",\n            \"W\",\n            \"X\",\n            \"Y\",\n            \"Z\",\n            \"关闭\"});\n            this.comboBoxEasyMouse.Location = new System.Drawing.Point(490, 122);\n            this.comboBoxEasyMouse.Name = \"comboBoxEasyMouse\";\n            this.comboBoxEasyMouse.Size = new System.Drawing.Size(56, 21);\n            this.comboBoxEasyMouse.TabIndex = 208;\n            this.comboBoxEasyMouse.Text = \"E\";\n            this.toolTip.SetToolTip(this.comboBoxEasyMouse, \"切换易动功能的开关，易动设置为按住按键开启时该切换无效。\");\n            this.comboBoxEasyMouse.TextChanged += new System.EventHandler(this.ComboBoxEasyMouse_TextChanged);\n            // \n            // checkBoxDrawMouse\n            // \n            this.checkBoxDrawMouse.AutoSize = true;\n            this.checkBoxDrawMouse.Checked = true;\n            this.checkBoxDrawMouse.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxDrawMouse.Location = new System.Drawing.Point(9, 118);\n            this.checkBoxDrawMouse.Name = \"checkBoxDrawMouse\";\n            this.checkBoxDrawMouse.Size = new System.Drawing.Size(117, 17);\n            this.checkBoxDrawMouse.TabIndex = 171;\n            this.checkBoxDrawMouse.Text = \"绘制鼠标光标(&D)\";\n            this.toolTip.SetToolTip(this.checkBoxDrawMouse, \"在 Win10 以上，如果电脑没插鼠标，那么默认不会显示鼠标光标，需要单独绘制。\");\n            this.checkBoxDrawMouse.UseVisualStyleBackColor = true;\n            this.checkBoxDrawMouse.CheckedChanged += new System.EventHandler(this.CheckBoxDrawMouse_CheckedChanged);\n            // \n            // checkBoxMouseMoveRelatively\n            // \n            this.checkBoxMouseMoveRelatively.AutoSize = true;\n            this.checkBoxMouseMoveRelatively.Checked = true;\n            this.checkBoxMouseMoveRelatively.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxMouseMoveRelatively.Location = new System.Drawing.Point(268, 53);\n            this.checkBoxMouseMoveRelatively.Name = \"checkBoxMouseMoveRelatively\";\n            this.checkBoxMouseMoveRelatively.Size = new System.Drawing.Size(131, 17);\n            this.checkBoxMouseMoveRelatively.TabIndex = 170;\n            this.checkBoxMouseMoveRelatively.Text = \"鼠标相对移动(&M)\";\n            this.toolTip.SetToolTip(this.checkBoxMouseMoveRelatively, \"提供不同屏幕配置和多屏使用的支持。\");\n            this.checkBoxMouseMoveRelatively.UseVisualStyleBackColor = true;\n            this.checkBoxMouseMoveRelatively.CheckedChanged += new System.EventHandler(this.CheckBoxMouseMoveRelatively_CheckedChanged);\n            // \n            // checkBoxHideMouse\n            // \n            this.checkBoxHideMouse.AutoSize = true;\n            this.checkBoxHideMouse.Checked = true;\n            this.checkBoxHideMouse.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxHideMouse.Location = new System.Drawing.Point(9, 96);\n            this.checkBoxHideMouse.Name = \"checkBoxHideMouse\";\n            this.checkBoxHideMouse.Size = new System.Drawing.Size(156, 17);\n            this.checkBoxHideMouse.TabIndex = 169;\n            this.checkBoxHideMouse.Text = \"移出屏幕隐藏鼠标(&H)\";\n            this.toolTip.SetToolTip(this.checkBoxHideMouse, \"鼠标移出屏幕后，把本设备光标隐藏在屏幕顶部，消除当前窗口焦点，使键盘输入转移到被控电脑。\");\n            this.checkBoxHideMouse.UseVisualStyleBackColor = true;\n            this.checkBoxHideMouse.CheckedChanged += new System.EventHandler(this.CheckBoxHideMouse_CheckedChanged);\n            // \n            // checkBoxBlockMouseAtCorners\n            // \n            this.checkBoxBlockMouseAtCorners.AutoSize = true;\n            this.checkBoxBlockMouseAtCorners.Location = new System.Drawing.Point(268, 75);\n            this.checkBoxBlockMouseAtCorners.Name = \"checkBoxBlockMouseAtCorners\";\n            this.checkBoxBlockMouseAtCorners.Size = new System.Drawing.Size(172, 17);\n            this.checkBoxBlockMouseAtCorners.TabIndex = 172;\n            this.checkBoxBlockMouseAtCorners.Text = \"屏幕四角阻挡\";\n            this.toolTip.SetToolTip(this.checkBoxBlockMouseAtCorners, \"在屏幕四角处阻挡跨界，防止误触。\");\n            this.checkBoxBlockMouseAtCorners.UseVisualStyleBackColor = true;\n            this.checkBoxBlockMouseAtCorners.CheckedChanged += new System.EventHandler(this.CheckBoxBlockMouseAtCorners_CheckedChanged);\n            // \n            // checkBoxCircle\n            // \n            this.checkBoxCircle.AutoSize = true;\n            this.checkBoxCircle.Location = new System.Drawing.Point(9, 11);\n            this.checkBoxCircle.Name = \"checkBoxCircle\";\n            this.checkBoxCircle.Size = new System.Drawing.Size(87, 17);\n            this.checkBoxCircle.TabIndex = 163;\n            this.checkBoxCircle.Text = \"循环移动(&W)\";\n            this.toolTip.SetToolTip(this.checkBoxCircle, \"鼠标移动超过最后一台电脑屏幕后，回到第一台电脑上。\");\n            this.checkBoxCircle.UseVisualStyleBackColor = true;\n            this.checkBoxCircle.CheckedChanged += new System.EventHandler(this.CheckBoxCircle_CheckedChanged);\n            // \n            // checkBoxBlockScreenSaver\n            // \n            this.checkBoxBlockScreenSaver.AutoSize = true;\n            this.checkBoxBlockScreenSaver.Checked = true;\n            this.checkBoxBlockScreenSaver.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxBlockScreenSaver.Location = new System.Drawing.Point(268, 32);\n            this.checkBoxBlockScreenSaver.Name = \"checkBoxBlockScreenSaver\";\n            this.checkBoxBlockScreenSaver.Size = new System.Drawing.Size(211, 17);\n            this.checkBoxBlockScreenSaver.TabIndex = 168;\n            this.checkBoxBlockScreenSaver.Text = \"阻止屏保(&B)\";\n            this.toolTip.SetToolTip(this.checkBoxBlockScreenSaver, \"阻止被控电脑启动屏幕保护程序。\");\n            this.checkBoxBlockScreenSaver.UseVisualStyleBackColor = true;\n            this.checkBoxBlockScreenSaver.CheckedChanged += new System.EventHandler(this.CheckBoxBlockScreenSaver_CheckedChanged);\n            // \n            // checkBoxHideLogo\n            // \n            this.checkBoxHideLogo.AutoSize = true;\n            this.checkBoxHideLogo.Location = new System.Drawing.Point(9, 75);\n            this.checkBoxHideLogo.Name = \"checkBoxHideLogo\";\n            this.checkBoxHideLogo.Size = new System.Drawing.Size(164, 17);\n            this.checkBoxHideLogo.TabIndex = 167;\n            this.checkBoxHideLogo.Text = \"登录时不显示 &Logo\";\n            this.toolTip.SetToolTip(this.checkBoxHideLogo, \"隐藏登录桌面上的“微软无界鼠标”字样。\");\n            this.checkBoxHideLogo.UseVisualStyleBackColor = true;\n            this.checkBoxHideLogo.CheckedChanged += new System.EventHandler(this.CheckBoxHideLogo_CheckedChanged);\n            // \n            // checkBoxShareClipboard\n            // \n            this.checkBoxShareClipboard.AutoSize = true;\n            this.checkBoxShareClipboard.Checked = true;\n            this.checkBoxShareClipboard.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxShareClipboard.Location = new System.Drawing.Point(9, 32);\n            this.checkBoxShareClipboard.Name = \"checkBoxShareClipboard\";\n            this.checkBoxShareClipboard.Size = new System.Drawing.Size(101, 17);\n            this.checkBoxShareClipboard.TabIndex = 165;\n            this.checkBoxShareClipboard.Text = \"共享剪贴板(&S)\";\n            this.toolTip.SetToolTip(this.checkBoxShareClipboard, \"共享复制的内容，如果功能突然失效，按 Ctrl + Alt + Del 然后按 Esc 也许可以解决问题。\");\n            this.checkBoxShareClipboard.UseVisualStyleBackColor = true;\n            this.checkBoxShareClipboard.CheckedChanged += new System.EventHandler(this.CheckBoxShareClipboard_CheckedChanged);\n            // \n            // checkBoxDisableCAD\n            // \n            this.checkBoxDisableCAD.AutoSize = true;\n            this.checkBoxDisableCAD.Checked = true;\n            this.checkBoxDisableCAD.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxDisableCAD.Location = new System.Drawing.Point(268, 11);\n            this.checkBoxDisableCAD.Name = \"checkBoxDisableCAD\";\n            this.checkBoxDisableCAD.Size = new System.Drawing.Size(86, 17);\n            this.checkBoxDisableCAD.TabIndex = 166;\n            this.checkBoxDisableCAD.Text = \"禁用 Ctrl+Alt+Del 登录(&C)\";\n            this.toolTip.SetToolTip(this.checkBoxDisableCAD, \"不需要按 Ctrl+Alt+Del 登录\");\n            this.checkBoxDisableCAD.UseVisualStyleBackColor = true;\n            this.checkBoxDisableCAD.CheckedChanged += new System.EventHandler(this.CheckBoxDisableCAD_CheckedChanged);\n            // \n            // buttonOK\n            // \n            this.buttonOK.Location = new System.Drawing.Point(187, 328);\n            this.buttonOK.Name = \"buttonOK\";\n            this.buttonOK.Size = new System.Drawing.Size(75, 23);\n            this.buttonOK.TabIndex = 20;\n            this.buttonOK.Text = \"应用(&A)\";\n            this.toolTip.SetToolTip(this.buttonOK, \"保存设置，刷新连接。\");\n            this.buttonOK.UseVisualStyleBackColor = true;\n            this.buttonOK.Click += new System.EventHandler(this.ButtonOK_Click);\n            // \n            // checkBoxReverseLookup\n            // \n            this.checkBoxReverseLookup.AutoSize = true;\n            this.checkBoxReverseLookup.Location = new System.Drawing.Point(9, 141);\n            this.checkBoxReverseLookup.Name = \"checkBoxReverseLookup\";\n            this.checkBoxReverseLookup.Size = new System.Drawing.Size(196, 17);\n            this.checkBoxReverseLookup.TabIndex = 173;\n            this.checkBoxReverseLookup.Text = \"验证远程设备地址(&V)\";\n            this.toolTip.SetToolTip(this.checkBoxReverseLookup, \"通过反向 DNS 查找来验证远程电脑的 IP 地址（高级功能，如有疑问查看在线帮助）\");\n            this.checkBoxReverseLookup.UseVisualStyleBackColor = true;\n            this.checkBoxReverseLookup.CheckedChanged += new System.EventHandler(this.CheckBoxReverseLookup_CheckedChanged);\n            // \n            // checkBoxVKMap\n            // \n            this.checkBoxVKMap.Enabled = false;\n            this.checkBoxVKMap.AutoSize = true;\n            this.checkBoxVKMap.Location = new System.Drawing.Point(268, 98);\n            this.checkBoxVKMap.Name = \"checkBoxVKMap\";\n            this.checkBoxVKMap.Size = new System.Drawing.Size(115, 17);\n            this.checkBoxVKMap.TabIndex = 174;\n            this.checkBoxVKMap.Text = \"启用按键映射(&U)\";\n            this.toolTip.SetToolTip(this.checkBoxVKMap, \"使用按键映射来改变快捷键，详情参阅在线帮助。\");\n            this.checkBoxVKMap.UseVisualStyleBackColor = true;\n            this.checkBoxVKMap.CheckedChanged += new System.EventHandler(this.CheckBoxVKMap_CheckedChanged);\n            // \n            // comboBoxScreenCapture\n            // \n            this.comboBoxScreenCapture.Enabled = false;\n            this.comboBoxScreenCapture.FormattingEnabled = true;\n            this.comboBoxScreenCapture.Items.AddRange(new object[] {\n            \"A\",\n            \"B\",\n            \"C\",\n            \"D\",\n            \"E\",\n            \"F\",\n            \"G\",\n            \"H\",\n            \"I\",\n            \"J\",\n            \"K\",\n            \"L\",\n            \"M\",\n            \"N\",\n            \"O\",\n            \"P\",\n            \"Q\",\n            \"R\",\n            \"S\",\n            \"T\",\n            \"U\",\n            \"V\",\n            \"W\",\n            \"X\",\n            \"Y\",\n            \"Z\",\n            \"关闭\"});\n            this.comboBoxScreenCapture.Location = new System.Drawing.Point(230, 121);\n            this.comboBoxScreenCapture.Name = \"comboBoxScreenCapture\";\n            this.comboBoxScreenCapture.Size = new System.Drawing.Size(54, 21);\n            this.comboBoxScreenCapture.TabIndex = 210;\n            this.comboBoxScreenCapture.Text = \"S\";\n            this.toolTip.SetToolTip(this.comboBoxScreenCapture, \"按下快捷键，按住鼠标左键拖动选择屏幕区域，松手完成截屏。\");\n            this.comboBoxScreenCapture.TextChanged += new System.EventHandler(this.ComboBoxScreenCapture_TextChanged);\n            // \n            // checkBoxSameSubNet\n            // \n            this.checkBoxSameSubNet.AutoSize = true;\n            this.checkBoxSameSubNet.Location = new System.Drawing.Point(9, 162);\n            this.checkBoxSameSubNet.Name = \"checkBoxSameSubNet\";\n            this.checkBoxSameSubNet.Size = new System.Drawing.Size(114, 18);\n            this.checkBoxSameSubNet.TabIndex = 175;\n            this.checkBoxSameSubNet.Text = \"仅限内网控制\";\n            this.toolTip.SetToolTip(this.checkBoxSameSubNet, \"仅允许连接到同一内网 NNN.NNN.*.* 下的电脑，只支持 IPv4。\");\n            this.checkBoxSameSubNet.UseCompatibleTextRendering = true;\n            this.checkBoxSameSubNet.UseVisualStyleBackColor = true;\n            this.checkBoxSameSubNet.CheckedChanged += new System.EventHandler(this.CheckBoxSameSubNet_CheckedChanged);\n            // \n            // checkBoxClipNetStatus\n            // \n            this.checkBoxClipNetStatus.AutoSize = true;\n            this.checkBoxClipNetStatus.Location = new System.Drawing.Point(268, 119);\n            this.checkBoxClipNetStatus.Name = \"checkBoxClipNetStatus\";\n            this.checkBoxClipNetStatus.Size = new System.Drawing.Size(231, 18);\n            this.checkBoxClipNetStatus.TabIndex = 176;\n            this.checkBoxClipNetStatus.Text = \"显示剪贴板/网络活动通知(&N)\";\n            this.toolTip.SetToolTip(this.checkBoxClipNetStatus, \"剪贴板和网络状态发生变化时，发送系统通知。\");\n            this.checkBoxClipNetStatus.UseCompatibleTextRendering = true;\n            this.checkBoxClipNetStatus.UseVisualStyleBackColor = true;\n            this.checkBoxClipNetStatus.CheckedChanged += new System.EventHandler(this.CheckBoxClipNetStatus_CheckedChanged);\n            // \n            // checkBoxSendLog\n            // \n            this.checkBoxSendLog.AutoSize = true;\n            this.checkBoxSendLog.Location = new System.Drawing.Point(268, 142);\n            this.checkBoxSendLog.Name = \"checkBoxSendLog\";\n            this.checkBoxSendLog.Size = new System.Drawing.Size(95, 18);\n            this.checkBoxSendLog.TabIndex = 177;\n            this.checkBoxSendLog.Text = \"发送错误日志(&E)\";\n            this.toolTip.SetToolTip(this.checkBoxSendLog, \"发送匿名错误日志到微软车库来帮助改进本软件。\");\n            this.checkBoxSendLog.UseCompatibleTextRendering = true;\n            this.checkBoxSendLog.UseVisualStyleBackColor = true;\n            this.checkBoxSendLog.Visible = false;\n            this.checkBoxSendLog.CheckedChanged += new System.EventHandler(this.CheckBoxSendLog_CheckedChanged);\n            // \n            // groupBoxKeySetup\n            // \n            this.groupBoxKeySetup.Controls.Add(this.buttonNewKey);\n            this.groupBoxKeySetup.Controls.Add(this.textBoxEnc);\n            this.groupBoxKeySetup.Controls.Add(this.LabelEnc);\n            this.groupBoxKeySetup.Controls.Add(this.checkBoxShowKey);\n            this.groupBoxKeySetup.Location = new System.Drawing.Point(3, 6);\n            this.groupBoxKeySetup.Name = \"groupBoxKeySetup\";\n            this.groupBoxKeySetup.Size = new System.Drawing.Size(558, 66);\n            this.groupBoxKeySetup.TabIndex = 0;\n            this.groupBoxKeySetup.TabStop = false;\n            this.groupBoxKeySetup.Text = \" 连接(&S)\";\n            this.toolTip.SetToolTip(this.groupBoxKeySetup, \"数据通信使用该密码加密。\");\n            // \n            // buttonNewKey\n            // \n            this.buttonNewKey.Location = new System.Drawing.Point(471, 19);\n            this.buttonNewKey.Name = \"buttonNewKey\";\n            this.buttonNewKey.Size = new System.Drawing.Size(75, 23);\n            this.buttonNewKey.TabIndex = 22;\n            this.buttonNewKey.Text = \"生成(&K)\";\n            this.buttonNewKey.UseVisualStyleBackColor = true;\n            this.buttonNewKey.Click += new System.EventHandler(this.ButtonNewKey_Click);\n            // \n            // textBoxEnc\n            // \n            this.textBoxEnc.Location = new System.Drawing.Point(86, 19);\n            this.textBoxEnc.MaxLength = 22;\n            this.textBoxEnc.Name = \"textBoxEnc\";\n            this.textBoxEnc.PasswordChar = '*';\n            this.textBoxEnc.Size = new System.Drawing.Size(304, 20);\n            this.textBoxEnc.TabIndex = 3;\n            this.toolTip.SetToolTip(this.textBoxEnc, \"密码必须自动生成，不可以手动输入。将密码输入到其他设备建立连接。\");\n            // \n            // LabelEnc\n            // \n            this.LabelEnc.AutoSize = true;\n            this.LabelEnc.Location = new System.Drawing.Point(7, 25);\n            this.LabelEnc.Name = \"LabelEnc\";\n            this.LabelEnc.Size = new System.Drawing.Size(69, 13);\n            this.LabelEnc.TabIndex = 19;\n            this.LabelEnc.Text = \"密码:\";\n            // \n            // checkBoxShowKey\n            // \n            this.checkBoxShowKey.AutoSize = true;\n            this.checkBoxShowKey.Location = new System.Drawing.Point(396, 21);\n            this.checkBoxShowKey.Name = \"checkBoxShowKey\";\n            this.checkBoxShowKey.Size = new System.Drawing.Size(73, 17);\n            this.checkBoxShowKey.TabIndex = 4;\n            this.checkBoxShowKey.Text = \"显示(&S)\";\n            this.checkBoxShowKey.UseVisualStyleBackColor = true;\n            this.checkBoxShowKey.CheckedChanged += new System.EventHandler(this.CheckBoxShowKey_CheckedChanged);\n            // \n            // labelEasyMouse\n            // \n            this.labelEasyMouse.AutoSize = true;\n            this.labelEasyMouse.Location = new System.Drawing.Point(309, 98);\n            this.labelEasyMouse.Name = \"labelEasyMouse\";\n            this.labelEasyMouse.Size = new System.Drawing.Size(68, 13);\n            this.labelEasyMouse.TabIndex = 211;\n            this.labelEasyMouse.Text = \"易动模式:\";\n            this.toolTip.SetToolTip(this.labelEasyMouse, \"如果易动不选择常开，你也可以选择按住 Ctrl 或 Shift 来快速移动到其他电脑。\");\n            // \n            // comboBoxEasyMouseOption\n            // \n            this.comboBoxEasyMouseOption.Enabled = true;\n            this.comboBoxEasyMouseOption.FormattingEnabled = true;\n            this.comboBoxEasyMouseOption.Items.AddRange(new object[] {\n            \"开启\",\n            \"Ctrl\",\n            \"Shift\",\n            \"关闭\"});\n            this.comboBoxEasyMouseOption.Location = new System.Drawing.Point(490, 94);\n            this.comboBoxEasyMouseOption.Name = \"comboBoxEasyMouseOption\";\n            this.comboBoxEasyMouseOption.Size = new System.Drawing.Size(56, 21);\n            this.comboBoxEasyMouseOption.TabIndex = 212;\n            this.comboBoxEasyMouseOption.Text = \"开启\";\n            this.toolTip.SetToolTip(this.comboBoxEasyMouseOption, \"移动鼠标到屏幕边缘即可跨电脑移动。\");\n            this.comboBoxEasyMouseOption.TextChanged += new System.EventHandler(this.ComboBoxEasyMouseOption_TextChanged);\n            // \n            // checkBoxTransferFile\n            // \n            this.checkBoxTransferFile.AutoSize = true;\n            this.checkBoxTransferFile.Checked = true;\n            this.checkBoxTransferFile.CheckState = System.Windows.Forms.CheckState.Checked;\n            this.checkBoxTransferFile.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 7.8F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.checkBoxTransferFile.Location = new System.Drawing.Point(26, 51);\n            this.checkBoxTransferFile.Name = \"checkBoxTransferFile\";\n            this.checkBoxTransferFile.Size = new System.Drawing.Size(81, 17);\n            this.checkBoxTransferFile.TabIndex = 178;\n            this.checkBoxTransferFile.Text = \"自动传输文件(&T)\";\n            this.toolTip.SetToolTip(this.checkBoxTransferFile, \"共享复制的文件，复制文件小于 100MB 时，自动传输到别的电脑的剪贴板。\");\n            this.checkBoxTransferFile.UseVisualStyleBackColor = true;\n            this.checkBoxTransferFile.CheckedChanged += new System.EventHandler(this.CheckBoxTransferFile_CheckedChanged);\n            // \n            // toolTipManual\n            // \n            this.toolTipManual.ToolTipTitle = \"Microsoft® Visual Studio® 2010\";\n            // \n            // tabPageOther\n            // \n            this.tabPageOther.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));\n            this.tabPageOther.Controls.Add(this.groupBoxOtherOptions);\n            this.tabPageOther.Controls.Add(this.groupBoxShortcuts);\n            this.tabPageOther.Location = new System.Drawing.Point(4, 25);\n            this.tabPageOther.Name = \"tabPageOther\";\n            this.tabPageOther.Padding = new System.Windows.Forms.Padding(3);\n            this.tabPageOther.Size = new System.Drawing.Size(563, 362);\n            this.tabPageOther.TabIndex = 1;\n            this.tabPageOther.Text = \"配置\";\n            // \n            // groupBoxOtherOptions\n            // \n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxTransferFile);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxSendLog);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxClipNetStatus);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxSameSubNet);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxVKMap);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxReverseLookup);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxDrawMouse);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxMouseMoveRelatively);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxHideMouse);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxBlockMouseAtCorners);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxCircle);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxBlockScreenSaver);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxHideLogo);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxShareClipboard);\n            this.groupBoxOtherOptions.Controls.Add(this.checkBoxDisableCAD);\n            this.groupBoxOtherOptions.Dock = System.Windows.Forms.DockStyle.Top;\n            this.groupBoxOtherOptions.Location = new System.Drawing.Point(3, 3);\n            this.groupBoxOtherOptions.Name = \"groupBoxOtherOptions\";\n            this.groupBoxOtherOptions.Size = new System.Drawing.Size(557, 189);\n            this.groupBoxOtherOptions.TabIndex = 163;\n            this.groupBoxOtherOptions.TabStop = false;\n            // \n            // groupBoxShortcuts\n            // \n            this.groupBoxShortcuts.Controls.Add(this.comboBoxEasyMouseOption);\n            this.groupBoxShortcuts.Controls.Add(this.labelEasyMouse);\n            this.groupBoxShortcuts.Controls.Add(this.comboBoxScreenCapture);\n            this.groupBoxShortcuts.Controls.Add(this.labelScreenCapture);\n            this.groupBoxShortcuts.Controls.Add(this.comboBoxEasyMouse);\n            this.groupBoxShortcuts.Controls.Add(this.LabelToggleEasyMouse);\n            this.groupBoxShortcuts.Controls.Add(this.comboBoxReconnect);\n            this.groupBoxShortcuts.Controls.Add(this.comboBoxSwitchToAllPC);\n            this.groupBoxShortcuts.Controls.Add(this.comboBoxExitMM);\n            this.groupBoxShortcuts.Controls.Add(this.comboBoxLockMachine);\n            this.groupBoxShortcuts.Controls.Add(this.comboBoxShowSettings);\n            this.groupBoxShortcuts.Controls.Add(this.labelReconnect);\n            this.groupBoxShortcuts.Controls.Add(this.labelSwitch2AllPCMode);\n            this.groupBoxShortcuts.Controls.Add(this.radioButtonDisable);\n            this.groupBoxShortcuts.Controls.Add(this.radioButtonNum);\n            this.groupBoxShortcuts.Controls.Add(this.radioButtonF1);\n            this.groupBoxShortcuts.Controls.Add(this.labelLockMachine);\n            this.groupBoxShortcuts.Controls.Add(this.labelExitMM);\n            this.groupBoxShortcuts.Controls.Add(this.labelShowSettings);\n            this.groupBoxShortcuts.Controls.Add(this.labelSwitchBetweenMachine);\n            this.groupBoxShortcuts.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.groupBoxShortcuts.Location = new System.Drawing.Point(3, 198);\n            this.groupBoxShortcuts.Name = \"groupBoxShortcuts\";\n            this.groupBoxShortcuts.Size = new System.Drawing.Size(557, 161);\n            this.groupBoxShortcuts.TabIndex = 200;\n            this.groupBoxShortcuts.TabStop = false;\n            this.groupBoxShortcuts.Text = \" 快捷键(&K) \";\n\n\n            ToolTip groupBoxToolTip = new ToolTip();\n            groupBoxToolTip.SetToolTip(this.groupBoxShortcuts, \"以下设置由 PowerToys 设置界面控制.\");\n\n            foreach (Control control in this.groupBoxShortcuts.Controls)\n            {\n                control.Enabled = false;\n            }\n\n            // \n            // labelScreenCapture\n            // \n            this.labelScreenCapture.AutoSize = true;\n            this.labelScreenCapture.Location = new System.Drawing.Point(6, 124);\n            this.labelScreenCapture.Name = \"labelScreenCapture\";\n            this.labelScreenCapture.Size = new System.Drawing.Size(173, 13);\n            this.labelScreenCapture.TabIndex = 209;\n            this.labelScreenCapture.Text = \"区块截屏 Ctrl+Shift+:\";\n            // \n            // LabelToggleEasyMouse\n            // \n            this.LabelToggleEasyMouse.AutoSize = true;\n            this.LabelToggleEasyMouse.Location = new System.Drawing.Point(309, 125);\n            this.LabelToggleEasyMouse.Name = \"LabelToggleEasyMouse\";\n            this.LabelToggleEasyMouse.Size = new System.Drawing.Size(149, 13);\n            this.LabelToggleEasyMouse.TabIndex = 114;\n            this.LabelToggleEasyMouse.Text = \"切换易动 Ctrl+Alt+:\";\n            // \n            // comboBoxExitMM\n            // \n            this.comboBoxExitMM.Enabled = false;\n            this.comboBoxExitMM.FormattingEnabled = true;\n            this.comboBoxExitMM.Items.AddRange(new object[] {\n            \"A\",\n            \"B\",\n            \"C\",\n            \"D\",\n            \"E\",\n            \"F\",\n            \"G\",\n            \"H\",\n            \"I\",\n            \"J\",\n            \"K\",\n            \"L\",\n            \"M\",\n            \"N\",\n            \"O\",\n            \"P\",\n            \"Q\",\n            \"R\",\n            \"S\",\n            \"T\",\n            \"U\",\n            \"V\",\n            \"W\",\n            \"X\",\n            \"Y\",\n            \"Z\",\n            \"关闭\"});\n            this.comboBoxExitMM.Location = new System.Drawing.Point(490, 41);\n            this.comboBoxExitMM.Name = \"comboBoxExitMM\";\n            this.comboBoxExitMM.Size = new System.Drawing.Size(56, 21);\n            this.comboBoxExitMM.TabIndex = 204;\n            this.comboBoxExitMM.Text = \"Q\";\n            this.comboBoxExitMM.TextChanged += new System.EventHandler(this.ComboBoxExitMM_TextChanged);\n            // \n            // comboBoxShowSettings\n            // \n            this.comboBoxShowSettings.Enabled = false;\n            this.comboBoxShowSettings.FormattingEnabled = true;\n            this.comboBoxShowSettings.Items.AddRange(new object[] {\n            \"A\",\n            \"B\",\n            \"C\",\n            \"D\",\n            \"E\",\n            \"F\",\n            \"G\",\n            \"H\",\n            \"I\",\n            \"J\",\n            \"K\",\n            \"L\",\n            \"M\",\n            \"N\",\n            \"O\",\n            \"P\",\n            \"Q\",\n            \"R\",\n            \"S\",\n            \"T\",\n            \"U\",\n            \"V\",\n            \"W\",\n            \"X\",\n            \"Y\",\n            \"Z\",\n            \"关闭\"});\n            this.comboBoxShowSettings.Location = new System.Drawing.Point(230, 41);\n            this.comboBoxShowSettings.Name = \"comboBoxShowSettings\";\n            this.comboBoxShowSettings.Size = new System.Drawing.Size(54, 21);\n            this.comboBoxShowSettings.TabIndex = 203;\n            this.comboBoxShowSettings.Text = \"M\";\n            this.comboBoxShowSettings.TextChanged += new System.EventHandler(this.ComboBoxShowSettings_TextChanged);\n            // \n            // labelReconnect\n            // \n            this.labelReconnect.AutoSize = true;\n            this.labelReconnect.Location = new System.Drawing.Point(6, 98);\n            this.labelReconnect.Name = \"labelReconnect\";\n            this.labelReconnect.Size = new System.Drawing.Size(195, 13);\n            this.labelReconnect.TabIndex = 59;\n            this.labelReconnect.Text = \"刷新连接 Ctrl+Alt+:\";\n            // \n            // labelSwitch2AllPCMode\n            // \n            this.labelSwitch2AllPCMode.AutoSize = true;\n            this.labelSwitch2AllPCMode.Location = new System.Drawing.Point(309, 71);\n            this.labelSwitch2AllPCMode.Name = \"labelSwitch2AllPCMode\";\n            this.labelSwitch2AllPCMode.Size = new System.Drawing.Size(122, 13);\n            this.labelSwitch2AllPCMode.TabIndex = 33;\n            this.labelSwitch2AllPCMode.Text = \"同步模式:\";\n            // \n            // radioButtonDisable\n            // \n            this.radioButtonDisable.AutoSize = true;\n            this.radioButtonDisable.Location = new System.Drawing.Point(434, 14);\n            this.radioButtonDisable.Name = \"radioButtonDisable\";\n            this.radioButtonDisable.Size = new System.Drawing.Size(60, 17);\n            this.radioButtonDisable.TabIndex = 202;\n            this.radioButtonDisable.TabStop = true;\n            this.radioButtonDisable.Text = \"关闭(&D)\";\n            this.radioButtonDisable.UseVisualStyleBackColor = true;\n            this.radioButtonDisable.CheckedChanged += new System.EventHandler(this.RadioButton_CheckedChanged);\n            // \n            // radioButtonNum\n            // \n            this.radioButtonNum.AutoSize = true;\n            this.radioButtonNum.Location = new System.Drawing.Point(346, 15);\n            this.radioButtonNum.Name = \"radioButtonNum\";\n            this.radioButtonNum.Size = new System.Drawing.Size(67, 17);\n            this.radioButtonNum.TabIndex = 201;\n            this.radioButtonNum.TabStop = true;\n            this.radioButtonNum.Text = \"&1, 2, 3, 4\";\n            this.radioButtonNum.UseVisualStyleBackColor = true;\n            this.radioButtonNum.CheckedChanged += new System.EventHandler(this.RadioButton_CheckedChanged);\n            // \n            // radioButtonF1\n            // \n            this.radioButtonF1.AutoSize = true;\n            this.radioButtonF1.Location = new System.Drawing.Point(230, 14);\n            this.radioButtonF1.Name = \"radioButtonF1\";\n            this.radioButtonF1.Size = new System.Drawing.Size(91, 17);\n            this.radioButtonF1.TabIndex = 200;\n            this.radioButtonF1.TabStop = true;\n            this.radioButtonF1.Text = \"&F1, F2, F3, F4\";\n            this.radioButtonF1.UseVisualStyleBackColor = true;\n            this.radioButtonF1.CheckedChanged += new System.EventHandler(this.RadioButton_CheckedChanged);\n            // \n            // labelLockMachine\n            // \n            this.labelLockMachine.AutoSize = true;\n            this.labelLockMachine.Location = new System.Drawing.Point(6, 71);\n            this.labelLockMachine.Name = \"labelLockMachine\";\n            this.labelLockMachine.Size = new System.Drawing.Size(133, 13);\n            this.labelLockMachine.TabIndex = 31;\n            this.labelLockMachine.Text = \"全部锁屏 Ctrl+Alt+:\";\n            // \n            // labelExitMM\n            // \n            this.labelExitMM.AutoSize = true;\n            this.labelExitMM.Location = new System.Drawing.Point(309, 44);\n            this.labelExitMM.Name = \"labelExitMM\";\n            this.labelExitMM.Size = new System.Drawing.Size(138, 13);\n            this.labelExitMM.TabIndex = 29;\n            this.labelExitMM.Text = \"退出软件 Ctrl+Alt+Shift+:\";\n            // \n            // labelShowSettings\n            // \n            this.labelShowSettings.AutoSize = true;\n            this.labelShowSettings.Location = new System.Drawing.Point(6, 44);\n            this.labelShowSettings.Name = \"labelShowSettings\";\n            this.labelShowSettings.Size = new System.Drawing.Size(149, 13);\n            this.labelShowSettings.TabIndex = 27;\n            this.labelShowSettings.Text = \"打开设置 Ctrl+Alt+:\";\n            // \n            // labelSwitchBetweenMachine\n            // \n            this.labelSwitchBetweenMachine.AutoSize = true;\n            this.labelSwitchBetweenMachine.Location = new System.Drawing.Point(6, 18);\n            this.labelSwitchBetweenMachine.Name = \"labelSwitchBetweenMachine\";\n            this.labelSwitchBetweenMachine.Size = new System.Drawing.Size(179, 13);\n            this.labelSwitchBetweenMachine.TabIndex = 24;\n            this.labelSwitchBetweenMachine.Text = \"切换设备 Ctrl+Alt+:\";\n            // \n            // tabPageMain\n            // \n            this.tabPageMain.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));\n            this.tabPageMain.Controls.Add(this.buttonCancel);\n            this.tabPageMain.Controls.Add(this.groupBoxMachineMatrix);\n            this.tabPageMain.Controls.Add(this.groupBoxKeySetup);\n            this.tabPageMain.Controls.Add(this.buttonOK);\n            this.tabPageMain.Location = new System.Drawing.Point(4, 25);\n            this.tabPageMain.Name = \"tabPageMain\";\n            this.tabPageMain.Padding = new System.Windows.Forms.Padding(3);\n            this.tabPageMain.Size = new System.Drawing.Size(563, 362);\n            this.tabPageMain.TabIndex = 0;\n            this.tabPageMain.Text = \"设备\";\n            // \n            // buttonCancel\n            // \n            this.buttonCancel.Location = new System.Drawing.Point(290, 328);\n            this.buttonCancel.Name = \"buttonCancel\";\n            this.buttonCancel.Size = new System.Drawing.Size(75, 23);\n            this.buttonCancel.TabIndex = 21;\n            this.buttonCancel.Text = \"关闭(&C)\";\n            this.buttonCancel.UseVisualStyleBackColor = true;\n            this.buttonCancel.Click += new System.EventHandler(this.ButtonCancel_Click);\n            // \n            // groupBoxMachineMatrix\n            // \n            this.groupBoxMachineMatrix.BackColor = System.Drawing.Color.Transparent;\n            this.groupBoxMachineMatrix.Controls.Add(this.checkBoxTwoRow);\n            this.groupBoxMachineMatrix.Controls.Add(this.linkLabelReConfigure);\n            this.groupBoxMachineMatrix.Location = new System.Drawing.Point(3, 78);\n            this.groupBoxMachineMatrix.Name = \"groupBoxMachineMatrix\";\n            this.groupBoxMachineMatrix.Size = new System.Drawing.Size(558, 244);\n            this.groupBoxMachineMatrix.TabIndex = 5;\n            this.groupBoxMachineMatrix.TabStop = false;\n            this.groupBoxMachineMatrix.Text = \" 设备布局(&M) - 拖动设备图标排序，选中图标旁边的勾选框以输入设备名称。 \";\n            // \n            // linkLabelReConfigure\n            // \n            this.linkLabelReConfigure.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.linkLabelReConfigure.Location = new System.Drawing.Point(3, 221);\n            this.linkLabelReConfigure.Name = \"linkLabelReConfigure\";\n            this.linkLabelReConfigure.Size = new System.Drawing.Size(552, 20);\n            this.linkLabelReConfigure.TabIndex = 304;\n            this.linkLabelReConfigure.TabStop = true;\n            this.linkLabelReConfigure.Text = \"重新执行软件初始化\";\n            this.linkLabelReConfigure.TextAlign = System.Drawing.ContentAlignment.MiddleRight;\n            this.linkLabelReConfigure.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelReConfigure_LinkClicked);\n            // \n            // tabControlSetting\n            // \n            this.tabControlSetting.Appearance = System.Windows.Forms.TabAppearance.FlatButtons;\n            this.tabControlSetting.Controls.Add(this.tabPageMain);\n            this.tabControlSetting.Controls.Add(this.tabPageOther);\n            this.tabControlSetting.Controls.Add(this.tabPageAdvancedSettings);\n            this.tabControlSetting.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.tabControlSetting.Location = new System.Drawing.Point(0, 0);\n            this.tabControlSetting.Name = \"tabControlSetting\";\n            this.tabControlSetting.SelectedIndex = 0;\n            this.tabControlSetting.Size = new System.Drawing.Size(571, 391);\n            this.tabControlSetting.TabIndex = 20;\n            // \n            // tabPageAdvancedSettings\n            // \n            this.tabPageAdvancedSettings.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));\n            this.tabPageAdvancedSettings.Controls.Add(this.groupBoxName2IPPolicyList);\n            this.tabPageAdvancedSettings.Controls.Add(this.pictureBoxMouseWithoutBorders);\n            this.tabPageAdvancedSettings.Controls.Add(this.groupBoxDNS);\n            this.tabPageAdvancedSettings.Controls.Add(this.textBoxDNS);\n            this.tabPageAdvancedSettings.Location = new System.Drawing.Point(4, 25);\n            this.tabPageAdvancedSettings.Name = \"tabPageAdvancedSettings\";\n            this.tabPageAdvancedSettings.Padding = new System.Windows.Forms.Padding(3);\n            this.tabPageAdvancedSettings.Size = new System.Drawing.Size(563, 362);\n            this.tabPageAdvancedSettings.TabIndex = 2;\n            this.tabPageAdvancedSettings.Text = \"高级\";\n            //\n            // groupBoxName2IPPolicyList\n            // \n            this.groupBoxName2IPPolicyList.Controls.Add(this.textBoxMachineName2IPPolicyList);\n            this.groupBoxName2IPPolicyList.Dock = System.Windows.Forms.DockStyle.Top;\n            this.groupBoxName2IPPolicyList.Location = new System.Drawing.Point(3, 241);\n            this.groupBoxName2IPPolicyList.Name = \"groupBoxName2IPPolicyList\";\n            this.groupBoxName2IPPolicyList.Size = new System.Drawing.Size(357, 150);\n            this.groupBoxName2IPPolicyList.TabIndex = 1;\n            this.groupBoxName2IPPolicyList.TabStop = false;\n            this.groupBoxName2IPPolicyList.Text = \" 组策略设定的 IP 地址映射 [组策略控制]\";\n            this.groupBoxName2IPPolicyList.ForeColor = Color.DimGray;\n            this.groupBoxName2IPPolicyList.Visible = false;\n            //\n            // textBoxMachineName2IPPolicyList\n            // \n            this.textBoxMachineName2IPPolicyList.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.textBoxMachineName2IPPolicyList.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.textBoxMachineName2IPPolicyList.Location = new System.Drawing.Point(3, 172); // 3,172\n            this.textBoxMachineName2IPPolicyList.MaxLength = 1024;\n            this.textBoxMachineName2IPPolicyList.Multiline = true;\n            this.textBoxMachineName2IPPolicyList.Name = \"textBoxMachineName2IPPolicyList\";\n            this.textBoxMachineName2IPPolicyList.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;\n            this.textBoxMachineName2IPPolicyList.Size = new System.Drawing.Size(351, 131);\n            this.textBoxMachineName2IPPolicyList.TabIndex = 1;\n            this.textBoxMachineName2IPPolicyList.ReadOnly = true;\n            this.textBoxMachineName2IPPolicyList.Visible = false;\n            // \n            // pictureBoxMouseWithoutBorders\n            // \n            this.pictureBoxMouseWithoutBorders.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;\n            this.pictureBoxMouseWithoutBorders.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.pictureBoxMouseWithoutBorders.Location = new System.Drawing.Point(3, 241);\n            this.pictureBoxMouseWithoutBorders.Name = \"pictureBoxMouseWithoutBorders\";\n            this.pictureBoxMouseWithoutBorders.Size = new System.Drawing.Size(557, 118);\n            this.pictureBoxMouseWithoutBorders.TabIndex = 16;\n            this.pictureBoxMouseWithoutBorders.TabStop = false;\n            // \n            // groupBoxDNS\n            // \n            this.groupBoxDNS.Controls.Add(this.textBoxMachineName2IP);\n            this.groupBoxDNS.Dock = System.Windows.Forms.DockStyle.Top;\n            this.groupBoxDNS.Location = new System.Drawing.Point(3, 85);\n            this.groupBoxDNS.Name = \"groupBoxDNS\";\n            this.groupBoxDNS.Size = new System.Drawing.Size(557, 150);\n            this.groupBoxDNS.TabIndex = 0;\n            this.groupBoxDNS.TabStop = false;\n            this.groupBoxDNS.Text = \" IP 地址映射 \";\n            // \n            // textBoxMachineName2IP\n            // \n            this.textBoxMachineName2IP.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.textBoxMachineName2IP.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.textBoxMachineName2IP.Location = new System.Drawing.Point(3, 16);\n            this.textBoxMachineName2IP.MaxLength = 1024;\n            this.textBoxMachineName2IP.Multiline = true;\n            this.textBoxMachineName2IP.Name = \"textBoxMachineName2IP\";\n            this.textBoxMachineName2IP.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;\n            this.textBoxMachineName2IP.Size = new System.Drawing.Size(551, 131);\n            this.textBoxMachineName2IP.TabIndex = 0;\n            // \n            // textBoxDNS\n            // \n            this.textBoxDNS.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(246)))), ((int)(((byte)(245)))), ((int)(((byte)(242)))));\n            this.textBoxDNS.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.textBoxDNS.Dock = System.Windows.Forms.DockStyle.Top;\n            this.textBoxDNS.Location = new System.Drawing.Point(3, 3);\n            this.textBoxDNS.Multiline = true;\n            this.textBoxDNS.Name = \"textBoxDNS\";\n            this.textBoxDNS.ReadOnly = true;\n            this.textBoxDNS.Size = new System.Drawing.Size(557, 82);\n            this.textBoxDNS.TabIndex = 0;\n            this.textBoxDNS.TabStop = false;\n            this.textBoxDNS.Text = resources.GetString(\"textBoxDNS.Text\");\n            // \n            // linkLabelHelp\n            // \n            this.linkLabelHelp.AutoSize = true;\n            this.linkLabelHelp.Dock = System.Windows.Forms.DockStyle.Right;\n            this.linkLabelHelp.Location = new System.Drawing.Point(400, 0);\n            this.linkLabelHelp.Name = \"linkLabelHelp\";\n            this.linkLabelHelp.Size = new System.Drawing.Size(124, 13);\n            this.linkLabelHelp.TabIndex = 300;\n            this.linkLabelHelp.TabStop = true;\n            this.linkLabelHelp.Text = \"在线帮助(&H)\";\n            this.linkLabelHelp.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelHelp_LinkClicked);\n            // \n            // linkLabelMiniLog\n            // \n            this.linkLabelMiniLog.AutoSize = true;\n            this.linkLabelMiniLog.Dock = System.Windows.Forms.DockStyle.Right;\n            this.linkLabelMiniLog.Location = new System.Drawing.Point(524, 0);\n            this.linkLabelMiniLog.Name = \"linkLabelMiniLog\";\n            this.linkLabelMiniLog.Size = new System.Drawing.Size(47, 13);\n            this.linkLabelMiniLog.TabIndex = 301;\n            this.linkLabelMiniLog.TabStop = true;\n            this.linkLabelMiniLog.Text = \"运行日志\";\n            this.linkLabelMiniLog.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelMiniLog_LinkClicked);\n            // \n            // frmMatrix\n            // \n            this.AllowDrop = true;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;\n            this.BackColor = System.Drawing.SystemColors.Control;\n            this.ClientSize = new System.Drawing.Size(571, 391);\n            this.Controls.Add(this.linkLabelHelp);\n            this.Controls.Add(this.linkLabelMiniLog);\n            this.Controls.Add(this.tabControlSetting);\n            this.Controls.Add(this.pictureBoxMouseWithoutBorders0);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MaximizeBox = false;\n            this.Name = \"frmMatrix\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"无界鼠标 - 设置\";\n            this.TopMost = true;\n            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FrmMatrix_FormClosed);\n            this.Load += new System.EventHandler(this.FrmMatrix_Load);\n            this.Shown += new System.EventHandler(this.FrmMatrix_Shown);\n            this.DragDrop += new System.Windows.Forms.DragEventHandler(this.Form_DragDrop);\n            this.DragEnter += new System.Windows.Forms.DragEventHandler(this.Form_DragEnter);\n            this.DragOver += new System.Windows.Forms.DragEventHandler(this.Form_DragOver);\n            this.DragLeave += new System.EventHandler(this.FrmMatrix_DragLeave);\n            this.Resize += new System.EventHandler(this.FrmMatrix_Resize);\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders0)).EndInit();\n            this.groupBoxKeySetup.ResumeLayout(false);\n            this.groupBoxKeySetup.PerformLayout();\n            this.tabPageOther.ResumeLayout(false);\n            this.groupBoxOtherOptions.ResumeLayout(false);\n            this.groupBoxOtherOptions.PerformLayout();\n            this.groupBoxShortcuts.ResumeLayout(false);\n            this.groupBoxShortcuts.PerformLayout();\n            this.tabPageMain.ResumeLayout(false);\n            this.groupBoxMachineMatrix.ResumeLayout(false);\n            this.groupBoxMachineMatrix.PerformLayout();\n            this.tabControlSetting.ResumeLayout(false);\n            this.tabPageAdvancedSettings.ResumeLayout(false);\n            this.tabPageAdvancedSettings.PerformLayout();\n            this.groupBoxName2IPPolicyList.ResumeLayout(false);\n            this.groupBoxName2IPPolicyList.PerformLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMouseWithoutBorders)).EndInit();\n            this.groupBoxDNS.ResumeLayout(false);\n            this.groupBoxDNS.PerformLayout();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n        }\n\n        #endregion\n\n        private PictureBox pictureBoxMouseWithoutBorders0;\n        private ToolTip toolTip;\n        private ToolTip toolTipManual;\n        private TabPage tabPageOther;\n        private GroupBox groupBoxShortcuts;\n        private ComboBox comboBoxReconnect;\n        private ComboBox comboBoxSwitchToAllPC;\n        private ComboBox comboBoxExitMM;\n        private ComboBox comboBoxLockMachine;\n        private ComboBox comboBoxShowSettings;\n        private Label labelReconnect;\n        private Label labelSwitch2AllPCMode;\n        private RadioButton radioButtonDisable;\n        private RadioButton radioButtonNum;\n        private RadioButton radioButtonF1;\n        private Label labelLockMachine;\n        private Label labelExitMM;\n        private Label labelShowSettings;\n        private Label labelSwitchBetweenMachine;\n        private TabPage tabPageMain;\n        private Button buttonCancel;\n        private GroupBox groupBoxMachineMatrix;\n        private CheckBox checkBoxTwoRow;\n        private Button buttonOK;\n        private TabControl tabControlSetting;\n        private ComboBox comboBoxEasyMouse;\n        private Label LabelToggleEasyMouse;\n        private LinkLabel linkLabelHelp;\n        private TabPage tabPageAdvancedSettings;\n        private GroupBox groupBoxDNS;\n        private TextBox textBoxDNS;\n        private TextBox textBoxMachineName2IP;\n        private GroupBox groupBoxName2IPPolicyList;\n        private TextBox textBoxMachineName2IPPolicyList;\n        private PictureBox pictureBoxMouseWithoutBorders;\n        private GroupBox groupBoxOtherOptions;\n        private CheckBox checkBoxDrawMouse;\n        private CheckBox checkBoxMouseMoveRelatively;\n        private CheckBox checkBoxHideMouse;\n        private CheckBox checkBoxBlockMouseAtCorners;\n        private CheckBox checkBoxCircle;\n        private CheckBox checkBoxBlockScreenSaver;\n        private CheckBox checkBoxHideLogo;\n        private CheckBox checkBoxShareClipboard;\n        private CheckBox checkBoxDisableCAD;\n        private CheckBox checkBoxReverseLookup;\n        private CheckBox checkBoxVKMap;\n        private LinkLabel linkLabelMiniLog;\n        private ComboBox comboBoxScreenCapture;\n        private Label labelScreenCapture;\n        private LinkLabel linkLabelReConfigure;\n        private CheckBox checkBoxSameSubNet;\n        private CheckBox checkBoxClipNetStatus;\n        private CheckBox checkBoxSendLog;\n        private GroupBox groupBoxKeySetup;\n        private Button buttonNewKey;\n        private TextBox textBoxEnc;\n        private Label LabelEnc;\n        private CheckBox checkBoxShowKey;\n        private ComboBox comboBoxEasyMouseOption;\n        private Label labelEasyMouse;\n        private CheckBox checkBoxTransferFile;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMatrix.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Drawing;\nusing System.Globalization;\nusing System.Text.RegularExpressions;\nusing System.Windows.Forms;\n\nusing Microsoft.PowerToys.Telemetry;\n\n// <summary>\n//     Matrix/Settings form.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\nusing Timer = System.Windows.Forms.Timer;\n\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1300:SpecifyMessageBoxOptions\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#buttonOK_Click(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#buttonSendHello_Click(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1304:SpecifyCultureInfo\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#frmMatrix_Load(System.Object,System.EventArgs)\", MessageId = \"System.String.ToLower\", Justification = \"Dotnet port with style preservation\")]\n\n// [module: SuppressMessage(\"Microsoft.Mobility\", \"CA1601:DoNotUseTimersThatPreventPowerStateChanges\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#ChangeUI2OneRow(System.Boolean)\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#logoTimer_Tick(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Usage\", \"CA2213:DisposableFieldsShouldBeDisposed\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#Dispose(System.Boolean)\", MessageId = \"logoBitmap\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Mobility\", \"CA1601:DoNotUseTimersThatPreventPowerStateChanges\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#frmMatrix_Shown(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmMatrix.#PaintMyLogo()\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Style\", \"IDE1006:Naming Styles\", Scope = \"member\", Target = \"~M:MouseWithoutBorders.FrmMatrix.M_EnabledChanged(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n\nnamespace MouseWithoutBorders\n{\n    internal partial class FrmMatrix : System.Windows.Forms.Form, IDisposable\n    {\n#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager\n        private Timer helperTimer;\n#pragma warning restore CA2213\n        private bool formShown;\n        private int formOrgHeight;\n        private bool matrixOneRow;\n\n        internal FrmMatrix()\n        {\n            InitializeComponent();\n\n            textBoxEnc.Font = new System.Drawing.Font(Control.DefaultFont.Name, 12F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, 0);\n\n            Text = Application.ProductName + \" \" + Application.ProductVersion + \" - 设置\";\n            toolTip.ToolTipTitle = Application.ProductName;\n            toolTipManual.ToolTipTitle = Application.ProductName;\n            labelExitMM.Text = \"退出软件, Ctrl+Alt+Shift+:\";\n            textBoxMachineName2IP.Text = Setting.Values.Name2IP;\n        }\n\n        private void ButtonCancel_Click(object sender, EventArgs e)\n        {\n            buttonCancel.Enabled = false;\n            Close();\n            Common.MatrixForm = null;\n        }\n\n        private void ButtonOK_Click(object sender, EventArgs e)\n        {\n            buttonOK.Enabled = false;\n\n            if (!UpdateKey(Regex.Replace(textBoxEnc.Text, @\"\\s+\", string.Empty)))\n            {\n                buttonOK.Enabled = true;\n                return;\n            }\n\n            string[] st = new string[Common.MAX_MACHINE];\n            for (int i = 0; i < Common.MAX_MACHINE; i++)\n            {\n                if (machines[i].MachineEnabled)\n                {\n                    for (int j = 0; j < i; j++)\n                    {\n                        if (st[j].Equals(machines[i].MachineName, StringComparison.OrdinalIgnoreCase))\n                        {\n                            machines[i].MachineName = string.Empty;\n                            machines[i].MachineEnabled = false;\n                        }\n                    }\n\n                    st[i] = machines[i].MachineName;\n                }\n                else\n                {\n                    st[i] = string.Empty;\n                }\n            }\n\n            Common.MachineMatrix = st;\n            Setting.Values.MatrixOneRow = matrixOneRow = !checkBoxTwoRow.Checked;\n\n            if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())\n            {\n                Program.StartService();\n                Common.ShowToolTip(\"新设置应用于物理控制台会话！\", 3000, ToolTipIcon.Warning, false);\n            }\n            else\n            {\n                SocketStuff.InvalidKeyFound = false;\n                showInvalidKeyMessage = false;\n                Common.ReopenSocketDueToReadError = true;\n                Common.ReopenSockets(true);\n\n                for (int i = 0; i < 10; i++)\n                {\n                    if (Common.AtLeastOneSocketConnected())\n                    {\n                        Common.MMSleep(0.5);\n                        break;\n                    }\n\n                    Common.MMSleep(0.2);\n                }\n\n                Common.SendMachineMatrix();\n            }\n\n            buttonOK.Enabled = true;\n        }\n\n        internal void UpdateKeyTextBox()\n        {\n            _ = Common.GetUserName();\n            textBoxEnc.Text = Common.MyKey;\n        }\n\n        private void InitAll()\n        {\n            formOrgHeight = Height;\n            matrixOneRow = Setting.Values.MatrixOneRow;\n            CreateMachines();\n            LoadSettingsToUI();\n            UpdateKeyTextBox();\n        }\n\n        private void LoadMachines()\n        {\n            bool meAdded = false;\n            string machineName;\n\n            if (Common.MachineMatrix != null && Common.MachineMatrix.Length == Common.MAX_MACHINE)\n            {\n                Logger.LogDebug(\"LoadMachines: Machine Matrix: \" + Setting.Values.MachineMatrixString);\n\n                for (int i = 0; i < Common.MAX_MACHINE; i++)\n                {\n                    machineName = Common.MachineMatrix[i].Trim();\n                    machines[i].MachineName = machineName;\n\n                    if (string.IsNullOrEmpty(machineName))\n                    {\n                        machines[i].CheckAble = true;\n                    }\n                    else\n                    {\n                        machines[i].MachineEnabled = true;\n                    }\n\n                    bool found = Common.MachinePool.TryFindMachineByName(machineName, out MachineInf machineInfo);\n                    if (found)\n                    {\n                        if (machineInfo.Id == Common.MachineID)\n                        {\n                            machines[i].LocalHost = true;\n                            meAdded = true;\n                        }\n                    }\n                }\n            }\n\n            if (!meAdded)\n            {\n                foreach (Machine m in machines)\n                {\n                    if (string.IsNullOrEmpty(m.MachineName))\n                    {\n                        m.MachineName = Common.MachineName.Trim();\n                        m.LocalHost = true;\n                        meAdded = true;\n                        break;\n                    }\n                }\n            }\n        }\n\n        private void CheckBoxShowKey_CheckedChanged(object sender, EventArgs e)\n        {\n            textBoxEnc.PasswordChar = checkBoxShowKey.Checked ? (char)0 : '*';\n        }\n\n        private void FrmMatrix_Shown(object sender, EventArgs e)\n        {\n            if (Setting.Values.FirstRun)\n            {\n                Setting.Values.FirstRun = false;\n                Common.ReopenSockets(false);\n\n                /*\n                string fireWallLog = Path.GetDirectoryName(Application.ExecutablePath) + \"\\\\FirewallError.log\";\n\n                if (File.Exists(fireWallLog))\n                {\n                    //@\"http://bing.com/search?q=Allow+a+program+through+Windows+Firewall\"\n\n                    MessageBox.Show(Application.ProductName + \" was unable to add itself to the Firewall exception list.\\r\\n\" +\n                        \"The following application needs to be added to the Firewall exception list:\\r\\n\\r\\n\" +\n                        Application.ExecutablePath +\n                        \"\\r\\n\\r\\nYou can go to bing.com and do a search on\" + \"\\r\\n'Allow a program through Windows Firewall' to know how.\",\n                        Application.ProductName,\n                        MessageBoxButtons.OK, MessageBoxIcon.Error);\n                }\n\n                linkLabelHelp_LinkClicked(null, null);\n                 * */\n            }\n\n            InitAll();\n\n            if (Setting.Values.IsMyKeyRandom)\n            {\n                Setting.Values.IsMyKeyRandom = false;\n                checkBoxShowKey.Checked = true;\n            }\n\n            if (helperTimer == null)\n            {\n                helperTimer = new Timer();\n                helperTimer.Interval = 200;\n                helperTimer.Tick += new EventHandler(HelperTimer_Tick);\n                helperTimer.Start();\n            }\n\n            formShown = true;\n        }\n\n        private void FrmMatrix_FormClosed(object sender, FormClosedEventArgs e)\n        {\n            /*\n            if (logoTimer != null)\n            {\n                logoTimer.Stop();\n                logoTimer.Dispose();\n                logoTimer = null;\n            }\n             * */\n\n            if (helperTimer != null)\n            {\n                helperTimer.Stop();\n                helperTimer.Dispose();\n                helperTimer = null;\n            }\n\n            // if (logoBitmap != null) logoBitmap.Dispose();\n            Common.MatrixForm = null;\n        }\n\n        private int pivot;\n        private Bitmap logoBitmap;\n\n        private void PaintMyLogo()\n        {\n            if (!Visible || !(tabControlSetting.SelectedTab == tabPageAdvancedSettings))\n            {\n                return;\n            }\n\n            uint rv = 0;\n            try\n            {\n                Color c;\n                uint cl;\n                double dC;\n                logoBitmap ??= new Bitmap(pictureBoxMouseWithoutBorders0.BackgroundImage);\n                int bWidth = logoBitmap.Width;\n                int bHeight = logoBitmap.Height;\n                double dx = (double)pictureBoxMouseWithoutBorders.Width / bWidth;\n                double dy = (double)pictureBoxMouseWithoutBorders.Height / bHeight;\n\n                IntPtr hdc = NativeMethods.GetWindowDC(pictureBoxMouseWithoutBorders.Handle);\n                for (int i = 0; i < bWidth; i++)\n                {\n                    for (int j = 0; j < bHeight; j++)\n                    {\n                        c = logoBitmap.GetPixel(i, j);\n\n                        // c.G > 245\n                        if (c.R < 240 && c.B < 240)\n                        {\n                            dC = Math.Abs(pivot - i);\n                            if (bWidth - pivot + i < dC)\n                            {\n                                dC = bWidth - pivot + i;\n                            }\n\n                            if (bWidth - i + pivot < dC)\n                            {\n                                dC = bWidth - i + pivot;\n                            }\n\n                            dC /= bWidth;\n\n                            // c = Color.FromArgb(80, (int)(255 - 255 * dC), 80);\n                            cl = (160 << 16) | ((uint)(255 - (255 * dC)) << 8) | 160;\n\n                            // Using GDI SetPixel so we dont have to assign the image later on\n                            // b.SetPixel(i, j, c);\n                            rv = NativeMethods.SetPixel(hdc, (int)(i * dx), (int)(j * dy), cl);\n                        }\n                    }\n                }\n\n                // Image im = pictureBoxMouseWithoutBorders.BackgroundImage;\n                // pictureBoxMouseWithoutBorders.BackgroundImage = b;\n                // if (im != null) im.Dispose();\n                rv = (uint)NativeMethods.ReleaseDC(pictureBoxMouseWithoutBorders.Handle, hdc);\n                pivot = (pivot + 5) % bWidth;\n            }\n            catch (Exception ee)\n            {\n                Logger.Log(ee);\n                Logger.Log(rv.ToString(CultureInfo.CurrentCulture));\n            }\n        }\n\n        private void AddNewMachine()\n        {\n            string newMachine;\n            Machine unUsedMachine;\n\n            foreach (MachineInf inf in Common.MachinePool.ListAllMachines())\n            {\n                bool found = false;\n                unUsedMachine = null;\n                newMachine = inf.Name.Trim();\n                foreach (Machine m in machines)\n                {\n                    if (m.MachineName.Equals(\n                        newMachine,\n                        StringComparison.OrdinalIgnoreCase))\n                    {\n                        found = true;\n                    }\n                    else if (unUsedMachine == null && string.IsNullOrEmpty(m.MachineName.Trim()))\n                    {\n                        unUsedMachine = m;\n                    }\n                }\n\n                if (!found && unUsedMachine != null)\n                {\n                    unUsedMachine.MachineName = newMachine;\n                }\n            }\n        }\n\n        private int helperTimerCounter;\n        private bool showInvalidKeyMessage;\n\n        private void HelperTimer_Tick(object sender, EventArgs e)\n        {\n            string keyNotMatchedMachines = string.Empty;\n\n            if (Setting.Values.Changed)\n            {\n                Setting.Values.Changed = false;\n                matrixOneRow = Setting.Values.MatrixOneRow;\n                LoadSettingsToUI();\n\n                /*\n                if (!Common.InMachineMatrix(Common.MachineName))\n                {\n                    foreach (Machine m in machines)\n                    {\n                        if (!m.LocalHost)\n                        {\n                            m.MachineEnabled = false;\n                        }\n                    }\n                }\n                 * */\n            }\n\n            helperTimerCounter++;\n\n            // 1 sec\n            if (helperTimerCounter % 5 == 0)\n            {\n                comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString();\n\n                if (!textBoxMachineName2IP.Text.Equals(Setting.Values.Name2IP, StringComparison.OrdinalIgnoreCase))\n                {\n                    Setting.Values.Name2IP = textBoxMachineName2IP.Text;\n                }\n\n                // 2 times\n                if (helperTimerCounter < 15)\n                {\n                    Common.SendHello();\n                }\n\n                AddNewMachine();\n            }\n\n            // NOTE(@yuyoyuppe): this option is deprecated\n            // checkBoxVKMap.Checked = Setting.Values.UseVKMap;\n            foreach (Machine m in machines)\n            {\n                if (m.StatusClient != SocketStatus.NA)\n                {\n                    m.StatusClient = SocketStatus.NA;\n                }\n\n                if (m.StatusServer != SocketStatus.NA)\n                {\n                    m.StatusServer = SocketStatus.NA;\n                }\n            }\n\n            SocketStuff sk = Common.Sk;\n\n            if (sk != null)\n            {\n                lock (sk.TcpSocketsLock)\n                {\n                    if (sk.TcpSockets != null)\n                    {\n                        foreach (TcpSk t in sk.TcpSockets)\n                        {\n                            if (t.Status == SocketStatus.InvalidKey)\n                            {\n                                keyNotMatchedMachines += string.Format(CultureInfo.CurrentCulture, \"[{0}]\", t.MachineName);\n                            }\n\n                            foreach (Machine m in machines)\n                            {\n                                if (m.MachineEnabled)\n                                {\n                                    if (m.MachineName.Equals(t.MachineName, StringComparison.OrdinalIgnoreCase))\n                                    {\n                                        if (t.IsClient)\n                                        {\n                                            if (t.Status > m.StatusClient)\n                                            {\n                                                m.StatusClient = t.Status;\n                                            }\n                                        }\n                                        else\n                                        {\n                                            if (t.Status > m.StatusServer)\n                                            {\n                                                m.StatusServer = t.Status;\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n\n            if (SocketStuff.InvalidKeyFound)\n            {\n                if (!showInvalidKeyMessage)\n                {\n                    showInvalidKeyMessage = true;\n\n                    Common.ShowToolTip(\n                        \"密码不正确。\\r\\n请检查是否在所有电脑上都输入了同一个密码。\\r\\n并检查您运行的是否都是同一版本的 \"\n                        + Application.ProductName + \"。\\r\\n\" + keyNotMatchedMachines + \"\\r\\n本软件版本: \" + FrmAbout.AssemblyVersion,\n                        20000,\n                        ToolTipIcon.Warning,\n                        Setting.Values.ShowClipNetStatus);\n                }\n            }\n            else\n            {\n                showInvalidKeyMessage = false;\n            }\n\n            PaintMyLogo();\n        }\n\n        private void ShowKeyErrorMsg(string msg)\n        {\n            Common.ShowToolTip(msg, 10000, ToolTipIcon.Error, false);\n            _ = textBoxEnc.Focus();\n            textBoxEnc.SelectAll();\n        }\n\n        private bool UpdateKey(string newKey)\n        {\n            if (!Common.IsKeyValid(newKey, out string rv))\n            {\n                ShowKeyErrorMsg(rv);\n                return false;\n            }\n\n            if (!newKey.Equals(Common.MyKey, StringComparison.OrdinalIgnoreCase))\n            {\n                Common.MyKey = newKey;\n                Common.GeneratedKey = false;\n            }\n\n            Common.MagicNumber = Common.Get24BitHash(Common.MyKey);\n            return true;\n        }\n\n        private readonly Machine[] machines = new Machine[Common.MAX_MACHINE];\n        private Machine dragDropMachine;\n        private Machine desMachine;\n        private Machine desMachineX;\n        private Machine desMachineY;\n        private Machine oldDesMachine;\n        private Point desMachinePos;\n        private Point oldDesMachinePos;\n\n        private void CreateMachines()\n        {\n            for (int i = 0; i < Common.MAX_MACHINE; i++)\n            {\n                Machine m = new();\n                m.MouseDown += Machine_MouseDown;\n                m.EnabledChanged += new EventHandler(M_EnabledChanged);\n                m.Parent = groupBoxMachineMatrix;\n                m.MachineEnabled = false;\n                machines[i] = m;\n            }\n\n            FrmMatrix_Resize(this, EventArgs.Empty);\n            ArrangeMachines();\n        }\n\n        private void ArrangeMachines()\n        {\n            Height = matrixOneRow ? formOrgHeight : formOrgHeight + 60;\n            int dx = (groupBoxMachineMatrix.Width - 40) / 4;\n            int yOffset = groupBoxMachineMatrix.Height / 3;\n\n            for (int i = 0; i < Common.MAX_MACHINE; i++)\n            {\n                machines[i].Left = matrixOneRow ? 22 + (i * dx) : 22 + dx + ((i % 2) * dx);\n                machines[i].Top = matrixOneRow ? yOffset : (yOffset / 2) + (i / 2 * (machines[i].Width + 2));\n                machines[i].Visible = true;\n            }\n        }\n\n        private void M_EnabledChanged(object sender, EventArgs e)\n        {\n            Machine m = sender as Machine;\n\n            SocketStuff sk = Common.Sk;\n\n            if (!m.MachineEnabled && sk != null)\n            {\n                lock (sk.TcpSocketsLock)\n                {\n                    if (sk.TcpSockets != null)\n                    {\n                        foreach (TcpSk t in sk.TcpSockets)\n                        {\n                            if (t.MachineName != null && t.MachineName.Equals(m.MachineName.Trim(), StringComparison.OrdinalIgnoreCase))\n                            {\n                                t.Status = SocketStatus.NA;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n\n        private void Machine_MouseDown(object sender, MouseEventArgs e)\n        {\n            oldDesMachine = desMachine = dragDropMachine = sender as Machine;\n            desMachinePos.X = desMachine.Left;\n            desMachinePos.Y = desMachine.Top;\n            oldDesMachinePos.X = oldDesMachine.Left;\n            oldDesMachinePos.Y = oldDesMachine.Top;\n\n            dragDropMachineOrgX = dragDropMachine.Left;\n            dragDropMachineOrgY = dragDropMachine.Top;\n            dragDropMachine.BringToFront();\n            _ = DoDragDrop(dragDropMachine, DragDropEffects.Move);\n        }\n\n        private int startX;\n        private int startY;\n        private int dragDropMachineOrgX;\n        private int dragDropMachineOrgY;\n\n        private void Form_DragEnter(object sender, DragEventArgs e)\n        {\n            startX = e.X;\n            startY = e.Y;\n            e.Effect = DragDropEffects.Move;\n        }\n\n        private bool IsOnSameRow(Machine m1, Machine m2)\n        {\n            return matrixOneRow || (m1 == dragDropMachine ? desMachinePos.Y : m1.Top) == m2.Top;\n        }\n\n        private bool IsOnSameCol(Machine m1, Machine m2)\n        {\n            return !matrixOneRow && (m1 == dragDropMachine ? desMachinePos.X : m1.Left) == m2.Left;\n        }\n\n        private long lastMove;\n\n        private void Form_DragOver(object sender, DragEventArgs e)\n        {\n            if (dragDropMachine == null)\n            {\n                return;\n            }\n\n            e.Effect = DragDropEffects.Move;\n\n            dragDropMachine.Left = dragDropMachineOrgX + (e.X - startX);\n            dragDropMachine.Top = dragDropMachineOrgY + (e.Y - startY);\n\n            /*\n            dragDropMachine.Left = e.X - dragDropMachine.MouseDownPos.X - Left - 3\n                - groupBoxMachineMatrix.Left - tabControlSetting.Left;\n            dragDropMachine.Top = e.Y - dragDropMachine.MouseDownPos.Y - Top - 25\n                - groupBoxMachineMatrix.Top - tabControlSetting.Top;\n             * */\n\n            if (!matrixOneRow && Common.GetTick() - lastMove < 500)\n            {\n                return;\n            }\n\n            int minX = Math.Abs(dragDropMachine.Left - desMachinePos.X);\n            int minY = Math.Abs(dragDropMachine.Top - desMachinePos.Y);\n\n            desMachineX = desMachineY = desMachine;\n\n            for (int i = 0; i < Common.MAX_MACHINE; i++)\n            {\n                if (machines[i] == dragDropMachine)\n                {\n                    continue;\n                }\n\n                if (IsOnSameRow(oldDesMachine, machines[i]))\n                {\n                    if (minX > Math.Abs(dragDropMachine.Left - machines[i].Left))\n                    {\n                        minX = Math.Abs(dragDropMachine.Left - machines[i].Left);\n                        desMachineX = machines[i];\n                    }\n                }\n\n                if (IsOnSameCol(oldDesMachine, machines[i]))\n                {\n                    if (minY > Math.Abs(dragDropMachine.Top - machines[i].Top))\n                    {\n                        minY = Math.Abs(dragDropMachine.Top - machines[i].Top);\n                        desMachineY = machines[i];\n                    }\n                }\n            }\n\n            oldDesMachine = desMachine;\n            desMachine = desMachineY == oldDesMachine ? desMachineX : desMachineX == oldDesMachine ? desMachineY : minX < minY ? desMachineX : desMachineY;\n\n            if (desMachine != oldDesMachine)\n            {\n                oldDesMachinePos.X = desMachinePos.X;\n                desMachinePos.X = desMachine.Left;\n\n                oldDesMachinePos.Y = desMachinePos.Y;\n                desMachinePos.Y = desMachine.Top;\n\n                desMachine.Left = oldDesMachinePos.X;\n                desMachine.Top = oldDesMachinePos.Y;\n\n                desMachine = dragDropMachine;\n\n                lastMove = Common.GetTick();\n            }\n        }\n\n        private void Form_DragDrop(object sender, DragEventArgs e)\n        {\n            if (desMachine != null)\n            {\n                dragDropMachine.Left = desMachinePos.X;\n                dragDropMachine.Top = desMachinePos.Y;\n\n                Machine tmp;\n                for (int i = 0; i < Common.MAX_MACHINE - 1; i++)\n                {\n                    for (int j = 0; j < Common.MAX_MACHINE - 1 - i; j++)\n                    {\n                        if (machines[j + 1].Top < machines[j].Top || (machines[j + 1].Top == machines[j].Top && machines[j + 1].Left < machines[j].Left))\n                        {\n                            tmp = machines[j];\n                            machines[j] = machines[j + 1];\n                            machines[j + 1] = tmp;\n                        }\n                    }\n                }\n            }\n        }\n\n        private void FrmMatrix_DragLeave(object sender, EventArgs e)\n        {\n            Form_DragDrop(sender, null);\n            InputSimulation.MouseUp();\n        }\n\n        private void LoadSettingsToUI()\n        {\n            checkBoxCircle.Checked = Setting.Values.MatrixCircle;\n            checkBoxTwoRow.Checked = !matrixOneRow;\n            checkBoxBlockMouseAtCorners.Checked = Setting.Values.BlockMouseAtCorners;\n            checkBoxDrawMouse.Checked = Setting.Values.DrawMouse;\n            checkBoxReverseLookup.Checked = Setting.Values.ReverseLookup;\n            checkBoxSameSubNet.Checked = Setting.Values.SameSubNetOnly;\n\n            // NOTE(@yuyoyuppe): this option is deprecated\n            // checkBoxVKMap.Checked = Setting.Values.UseVKMap;\n            foreach (Machine m in machines)\n            {\n                m.MachineName = string.Empty;\n                m.MachineEnabled = false;\n                m.LocalHost = false;\n            }\n\n            LoadMachines();\n        }\n\n        internal static readonly string[] Separator = new string[] { \"\\r\\n\" };\n\n        internal void ShowTip(ToolTipIcon icon, string text, int duration)\n        {\n            int x = 0;\n            text += \"\\r\\n \";\n            int y = (-text.Split(Separator, StringSplitOptions.None).Length * 15) - 30;\n\n            toolTipManual.Hide(this);\n\n            toolTipManual.ToolTipIcon = icon;\n            toolTipManual.Show(text, this, x, y, duration);\n        }\n\n        private void LinkLabelHelp_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            linkLabelHelp.Enabled = false;\n            linkLabelHelp.Enabled = true;\n        }\n\n        private void CheckBoxShareClipboard_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.ShareClipboard = checkBoxShareClipboard.Checked;\n\n            checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = Setting.Values.ShareClipboard;\n\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxTransferFile_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.TransferFile = checkBoxTransferFile.Checked;\n\n            ShowUpdateMessage();\n\n            Common.HasSwitchedMachineSinceLastCopy = true;\n        }\n\n        private void CheckBoxDisableCAD_CheckedChanged(object sender, EventArgs e)\n        {\n            if (!Common.RunWithNoAdminRight)\n            {\n                Common.ApplyCADSetting();\n                ShowUpdateMessage();\n            }\n        }\n\n        private void FrmMatrix_Load(object sender, EventArgs e)\n        {\n            if (Common.RunWithNoAdminRight)\n            {\n                checkBoxDisableCAD.Enabled = false;\n                checkBoxHideLogo.Enabled = false;\n            }\n\n            // Note(@htcfreek): Disable checkboxes of settings that we don't support in the PowerToys implementation\n            checkBoxDisableCAD.Enabled = false;\n            checkBoxDisableCAD.Text = checkBoxDisableCAD.Text + \" [不支持!]\";\n            checkBoxHideLogo.Enabled = false;\n            checkBoxHideLogo.Text = checkBoxHideLogo.Text + \" [不支持!]\";\n            checkBoxSendLog.Enabled = false;\n            checkBoxSendLog.Text = checkBoxSendLog.Text + \" [不支持!]\";\n\n            checkBoxShareClipboard.Checked = Setting.Values.ShareClipboard;\n\n            if (!Setting.Values.ShareClipboard)\n            {\n                checkBoxTransferFile.Enabled = checkBoxTransferFile.Checked = false;\n            }\n            else\n            {\n                checkBoxTransferFile.Checked = Setting.Values.TransferFile;\n            }\n\n            checkBoxDisableCAD.Checked = Setting.Values.DisableCAD;\n            checkBoxHideLogo.Checked = Setting.Values.HideLogonLogo;\n            checkBoxHideMouse.Checked = Setting.Values.HideMouse;\n            checkBoxBlockScreenSaver.Checked = Setting.Values.BlockScreenSaver;\n            checkBoxMouseMoveRelatively.Checked = Setting.Values.MoveMouseRelatively;\n            checkBoxClipNetStatus.Checked = Setting.Values.ShowClipNetStatus;\n            checkBoxSendLog.Checked = Setting.Values.SendErrorLogV2;\n\n            if (Setting.Values.HotKeySwitchMachine == (int)VK.F1)\n            {\n                radioButtonF1.Checked = true;\n            }\n            else if (Setting.Values.HotKeySwitchMachine == '1')\n            {\n                radioButtonNum.Checked = true;\n            }\n            else\n            {\n                radioButtonDisable.Checked = true;\n            }\n\n            comboBoxShowSettings.Text = \"关闭\";\n\n            comboBoxExitMM.Text = Setting.Values.HotKeyExitMM == 0 ? \"关闭\" : new string(new char[] { (char)Setting.Values.HotKeyExitMM });\n#if OBSOLETE_SHORTCUTS\n            comboBoxLockMachine.Text = Setting.Values.HotKeyLockMachine == 0 ? \"关闭\" : new string(new char[] { (char)Setting.Values.HotKeyLockMachine });\n\n            comboBoxReconnect.Text = Setting.Values.HotKeyReconnect == 0 ? \"关闭\" : new string(new char[] { (char)Setting.Values.HotKeyReconnect });\n\n            comboBoxSwitchToAllPC.Text = Setting.Values.HotKeySwitch2AllPC == 1\n                ? \"Ctrl*3\"\n                : Setting.Values.HotKeySwitch2AllPC == 0 ? \"关闭\" : new string(new char[] { (char)Setting.Values.HotKeySwitch2AllPC });\n\n            comboBoxEasyMouseOption.Text = ((EasyMouseOption)Setting.Values.EasyMouse).ToString();\n\n            comboBoxEasyMouse.Text = Setting.Values.HotKeyToggleEasyMouse == 0 ? \"关闭\" : new string(new char[] { (char)Setting.Values.HotKeyToggleEasyMouse });\n#endif\n\n            // Apply policy configuration on UI elements\n            // Has to be the last action\n            if (Setting.Values.ShareClipboardIsGpoConfigured)\n            {\n                checkBoxShareClipboard.Enabled = false;\n                checkBoxShareClipboard.Text += \" [组策略控制]\";\n\n                // transfer file setting depends on clipboard sharing\n                checkBoxTransferFile.Enabled = false;\n            }\n\n            if (Setting.Values.TransferFileIsGpoConfigured)\n            {\n                checkBoxTransferFile.Enabled = false;\n                checkBoxTransferFile.Text += \" [组策略控制]\";\n            }\n\n            if (Setting.Values.BlockScreenSaverIsGpoConfigured)\n            {\n                checkBoxBlockScreenSaver.Enabled = false;\n                checkBoxBlockScreenSaver.Text += \" [组策略控制]\";\n            }\n\n            if (Setting.Values.SameSubNetOnlyIsGpoConfigured)\n            {\n                checkBoxSameSubNet.Enabled = false;\n                checkBoxSameSubNet.Text += \" [组策略控制]\";\n            }\n\n            if (Setting.Values.ReverseLookupIsGpoConfigured)\n            {\n                checkBoxReverseLookup.Enabled = false;\n                checkBoxReverseLookup.Text += \" [组策略控制]\";\n            }\n\n            if (Setting.Values.Name2IpIsGpoConfigured)\n            {\n                textBoxMachineName2IP.Enabled = false;\n                groupBoxDNS.ForeColor = Color.DimGray;\n                groupBoxDNS.Text += \" [组策略控制]\";\n            }\n\n            if (Setting.Values.Name2IpPolicyListIsGpoConfigured)\n            {\n                pictureBoxMouseWithoutBorders.Visible = false;\n                groupBoxName2IPPolicyList.Visible = true;\n                textBoxMachineName2IPPolicyList.Visible = true;\n                textBoxMachineName2IPPolicyList.Text = Setting.Values.Name2IpPolicyList;\n            }\n        }\n\n        private void RadioButton_CheckedChanged(object sender, EventArgs e)\n        {\n            RadioButton r = sender as RadioButton;\n\n            if (r.Checked)\n            {\n                Setting.Values.HotKeySwitchMachine = sender.Equals(radioButtonF1) ? (int)VK.F1 : sender.Equals(radioButtonNum) ? '1' : 0;\n\n                ShowUpdateMessage();\n            }\n        }\n\n        private void ComboBoxShowSettings_TextChanged(object sender, EventArgs e)\n        {\n            ShowUpdateMessage();\n        }\n\n        private void ComboBoxExitMM_TextChanged(object sender, EventArgs e)\n        {\n            ShowUpdateMessage();\n        }\n\n        private void ComboBoxLockMachine_TextChanged(object sender, EventArgs e)\n        {\n#if OBSOLETE_SHORTCUTS\n            if (comboBoxLockMachine.Text.Contains(\"关闭\"))\n            {\n                Setting.Values.HotKeyLockMachine = 0;\n            }\n            else if (comboBoxLockMachine.Text.Length > 0)\n            {\n                Setting.Values.HotKeyLockMachine = comboBoxLockMachine.Text[0];\n            }\n#endif\n        }\n\n        private void ComboBoxSwitchToAllPC_TextChanged(object sender, EventArgs e)\n        {\n#if OBSOLETE_SHORTCUTS\n            if (comboBoxSwitchToAllPC.Text.Contains(\"关闭\"))\n            {\n                Setting.Values.HotKeySwitch2AllPC = 0;\n            }\n            else if (comboBoxSwitchToAllPC.Text.Contains(\"Ctrl*3\"))\n            {\n                Setting.Values.HotKeySwitch2AllPC = 1;\n            }\n            else if (comboBoxSwitchToAllPC.Text.Length > 0)\n            {\n                Setting.Values.HotKeySwitch2AllPC = comboBoxSwitchToAllPC.Text[0];\n            }\n#endif\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxHideLogo_CheckedChanged(object sender, EventArgs e)\n        {\n            ShowUpdateMessage();\n        }\n\n        private void ShowUpdateMessage()\n        {\n            if (!formShown)\n            {\n                return;\n            }\n\n            foreach (Control c in tabPageOther.Controls)\n            {\n                if (c != groupBoxShortcuts)\n                {\n                    c.Enabled = false;\n                }\n            }\n\n            foreach (Control c in groupBoxShortcuts.Controls)\n            {\n                if (c != pictureBoxMouseWithoutBorders)\n                {\n                    c.Enabled = false;\n                }\n            }\n\n            for (int i = 0; i < 3; i++)\n            {\n                Application.DoEvents();\n                Thread.Sleep(20);\n            }\n\n            foreach (Control c in tabPageOther.Controls)\n            {\n                if (c != groupBoxShortcuts)\n                {\n                    c.Enabled = true;\n                }\n            }\n\n            foreach (Control c in groupBoxShortcuts.Controls)\n            {\n                if (c != pictureBoxMouseWithoutBorders && c != comboBoxExitMM && c != comboBoxShowSettings && c != comboBoxScreenCapture)\n                {\n                    c.Enabled = true;\n                }\n            }\n        }\n\n        private void CheckBoxBlockScreenSaver_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.BlockScreenSaver = checkBoxBlockScreenSaver.Checked;\n            ShowUpdateMessage();\n        }\n\n        private void ComboBoxReconnect_TextChanged(object sender, EventArgs e)\n        {\n#if OBSOLETE_SHORTCUTS\n            if (comboBoxReconnect.Text.Contains(\"关闭\"))\n            {\n                Setting.Values.HotKeyReconnect = 0;\n            }\n            else if (comboBoxReconnect.Text.Length > 0)\n            {\n                Setting.Values.HotKeyReconnect = comboBoxReconnect.Text[0];\n            }\n#endif\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxCircle_CheckedChanged(object sender, EventArgs e)\n        {\n            if (Setting.Values.MatrixCircle != checkBoxCircle.Checked)\n            {\n                Setting.Values.MatrixCircle = checkBoxCircle.Checked;\n                ShowUpdateMessage();\n                Common.SendMachineMatrix();\n            }\n        }\n\n        private void CheckBoxBlockMouseAtCorners_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.BlockMouseAtCorners = checkBoxBlockMouseAtCorners.Checked;\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxHideMouse_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.HideMouse = checkBoxHideMouse.Checked;\n            ShowUpdateMessage();\n        }\n\n        private void ComboBoxEasyMouseOption_TextChanged(object sender, EventArgs e)\n        {\n            string selectedOption = comboBoxEasyMouseOption.Text;\n            int oldEasyMouseOption = Setting.Values.EasyMouse;\n\n            Setting.Values.EasyMouse = Enum.TryParse<EasyMouseOption>(selectedOption, out EasyMouseOption easyMouseOption) ? (int)easyMouseOption : (int)EasyMouseOption.开启;\n\n            if (oldEasyMouseOption != Setting.Values.EasyMouse)\n            {\n                ShowUpdateMessage();\n            }\n        }\n\n        private void ComboBoxEasyMouse_TextChanged(object sender, EventArgs e)\n        {\n#if OBSOLETE_SHORTCUTS\n            if (comboBoxEasyMouse.Text.Contains(\"关闭\"))\n            {\n                Setting.Values.HotKeyToggleEasyMouse = 0;\n            }\n            else if (comboBoxEasyMouse.Text.Length > 0)\n            {\n                Setting.Values.HotKeyToggleEasyMouse = comboBoxEasyMouse.Text[0];\n            }\n#endif\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxMouseMoveRelatively_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.MoveMouseRelatively = checkBoxMouseMoveRelatively.Checked;\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxDrawMouse_CheckedChanged(object sender, EventArgs e)\n        {\n            if (!(Setting.Values.DrawMouse = checkBoxDrawMouse.Checked))\n            {\n                CustomCursor.ShowFakeMouseCursor(int.MinValue, int.MinValue);\n            }\n\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxTwoRow_CheckedChanged(object sender, EventArgs e)\n        {\n            matrixOneRow = !checkBoxTwoRow.Checked;\n            ArrangeMachines();\n        }\n\n        private void ButtonNewKey_Click(object sender, EventArgs e)\n        {\n            string message = \"确定要生成新密码吗？\\r\\n\" +\n                \"所有现有的连接会被取消，您需要重新输入密码来建立所有连接。\";\n\n            if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == DialogResult.Yes)\n            {\n                Setting.Values.MyKey = Common.MyKey = Common.CreateRandomKey();\n                textBoxEnc.Text = Common.MyKey;\n                checkBoxShowKey.Checked = true;\n                Common.GeneratedKey = true;\n                ButtonOK_Click(null, null);\n                Common.ShowToolTip(\"新密码已生成，需要在其他电脑上输入新的密码来重新连接。\", 10000, ToolTipIcon.Info, false);\n            }\n        }\n\n        private void CheckBoxClipNetStatus_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.ShowClipNetStatus = checkBoxClipNetStatus.Checked;\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxSendLog_CheckedChanged(object sender, EventArgs e)\n        {\n            ShowUpdateMessage();\n        }\n\n        private void FrmMatrix_Resize(object sender, EventArgs e)\n        {\n            if (WindowState != FormWindowState.Minimized)\n            {\n                groupBoxMachineMatrix.Top = groupBoxKeySetup.Top + groupBoxKeySetup.Height + 10;\n                groupBoxMachineMatrix.Height = ClientSize.Height - groupBoxKeySetup.Height - (int)(buttonOK.Height * 3.5);\n                checkBoxTwoRow.Top = groupBoxMachineMatrix.Height - (int)(checkBoxTwoRow.Height * 1.4);\n                buttonOK.Top = groupBoxMachineMatrix.Bottom + (int)(buttonOK.Height * 0.3);\n                buttonCancel.Top = groupBoxMachineMatrix.Bottom + (int)(buttonCancel.Height * 0.3);\n                groupBoxShortcuts.Height = ClientSize.Height - groupBoxOtherOptions.Bottom - 40;\n                groupBoxDNS.Height = ClientSize.Height - pictureBoxMouseWithoutBorders.Height - textBoxDNS.Height - 70;\n            }\n        }\n\n        private void CheckBoxReverseLookup_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.ReverseLookup = checkBoxReverseLookup.Checked;\n            ShowUpdateMessage();\n        }\n\n        private void CheckBoxVKMap_CheckedChanged(object sender, EventArgs e)\n        {\n            // NOTE(@yuyoyuppe): this option is deprecated\n            // Setting.Values.UseVKMap = checkBoxVKMap.Checked;\n            ShowUpdateMessage();\n        }\n\n        private void LinkLabelMiniLog_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            string miniLog = Common.GetMiniLog(new[] { groupBoxOtherOptions.Controls, groupBoxShortcuts.Controls });\n\n            Clipboard.SetText(miniLog);\n            Common.ShowToolTip(\"运行日志已复制到剪贴板\", 30000, ToolTipIcon.Info, false);\n        }\n\n        private void ComboBoxScreenCapture_TextChanged(object sender, EventArgs e)\n        {\n            ShowUpdateMessage();\n        }\n\n        private void LinkLabelReConfigure_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)\n        {\n            string message = \"警告：这将清除当前布局，重置所有设置，重新运行软件初始教程。对于 PowerToys 用户，请使用 PowerToys 设置，而不是这个初始化。\\r\\n\";\n            message += \"你将需要重新初始化所有要连接的电脑。在接下去的选择窗口中，对于第一台电脑请选“否”，剩下的选“是”。\\r\\n\";\n            message += \"接着按照步骤完成配置。\\r\\n\\r\\n\";\n            message += \"您确定要继续吗？\";\n\n            if (MessageBox.Show(message, Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button2) == System.Windows.Forms.DialogResult.Yes)\n            {\n                PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIReconfigureEvent());\n                ButtonCancel_Click(this, new EventArgs());\n                Setting.Values.FirstRun = true;\n                Setting.Values.EasyMouse = (int)EasyMouseOption.开启;\n                Common.ClearComputerMatrix();\n                Common.ShowSetupForm(true);\n            }\n        }\n\n        private void CheckBoxSameSubNet_CheckedChanged(object sender, EventArgs e)\n        {\n            Setting.Values.SameSubNetOnly = checkBoxSameSubNet.Checked;\n            ShowUpdateMessage();\n        }\n\n#if USE_TO_CREATE_LOGO_BITMAP\n        private void PaintMyLogo()\n        {\n            Graphics g = Graphics.FromHwnd(this.Handle);\n            Font font = new Font(\"Chiller\", 40);\n            g.DrawString(Common.BinaryName, font, Brushes.Lime, comboBoxIPs.Right + 50, comboBoxIPs.Bottom - 5);\n\n            Bitmap b = new Bitmap(220, 100);\n            Graphics g2 = Graphics.FromImage(b);\n            g2.FillRectangle(Brushes.WhiteSmoke, 0, 0, 220, 100);\n            g2.DrawString(Common.BinaryName, font, Brushes.Lime, 0, 0);\n            b.Save(\"c:\\\\zzz.bmp\");\n            string p = \"\";\n            Color c;\n            int l = 0;\n            for (int i = 0; i < b.Width; i++)\n            {\n                for (int j = 0; j < b.Height; j++)\n                {\n                    c = b.GetPixel(i, j);\n                    if (c.G > 0)\n                    {\n                        p += \"{\" + i + \",\" + j + \"},\";\n                        l++;\n                    }\n                }\n                p += \"\\r\\n\";\n            }\n            //File.WriteAllText(\"c:\\\\zzz.txt\", l + \":\" + p, Encoding.Unicode);\n            b.Dispose();\n            g2.Dispose();\n        }\n#endif\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMatrix.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <assembly alias=\"System.Drawing\" name=\"System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\" />\n  <data name=\"pictureBoxMouseWithoutBorders0.BackgroundImage\" type=\"System.Drawing.Bitmap, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        iVBORw0KGgoAAAANSUhEUgAAAN4AAAAaCAYAAADYHuIVAAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO\n        vAAADrwBlbxySQAABjpJREFUeF7tmzF25DYQROeCvocPsUfwCXwB58433tSpQ4fOfAOZf96WWFtqkIA4\n        Inae+CtYTRMgGo1GExxpby8XFw/mj++6aNPceF++6+Li4vFcT7yLh/H3olunfl3036LPyvDG+7rIA/jv\n        oovjkIQe178WPRu/LPI5uH5bpFxh02H7fdHZaGzp26IZvNl4BEdO/bPIqSoawb44TibEM8bV/Zco1ImK\n        zIw5rp6tmsGbUXmvk0P5guzXXBfHyafFjKfBUdx/tPU0UZuzIac1Npr1PcYPM88nGlVY8PTza66Ll/tR\n        Cr0X+npMn/H9x/1HLZgbhWZe0q86smZH+CE6WnyvvjqX57ud62KFAvWe994/Fz1zTPMdFbUgRuTYrKe6\n        H+uro/AZvEbHA8eTj6Dws44LW99YfXZy07xnMb2wzXj3eQTyX2pB4jPHWU91f2XK7zHO4jU6vvCgjaZH\n        MclFsPi2Te2kz46fEFrxIMm2Es3j70f8Gez52iKPyxUkPfGa+W34no9n8DqykscXnc/YgYCh6l3vs+Mx\n        qd4ZdHpAFLCKLGiz6PG1Bacj9UWOjpfk18xNBy0fz+Q+sv8Kwc/dOhKQFPzMQlQbb9bj+lkgdh6viozr\n        LHp8bZFzIK/8WOca3dSPxP2YxX1kr1T+fuLVjwXh+OGbVLo23jZ+BCMRW6gNmkWvry3U10Xu6A8CfHOe\n        8UcCjI0cjY9mcR/ZN5j/7sW/UPFFkE068+jA5s/fxaCf5fhSfbGS7z4ur/xuT52RpNDrawtvX8UCPK8+\n        mmoc2dL+SPby9D5ydUFoIQiWoIKsPd4639qwvTAmcphIHmVcehcV1ZMZ9SawH5Fam1pjZDw0ZxLV7Yhr\n        rS8u9J7dkq8BHIlzxnjU1xbefwsV+9ycvXNyf7f+J4Riyroj5qN+yOnNma2xe/P0zcbrgQXzPr44OTHU\n        SlwCqzaanDud+JM55Unki8dEGT/77h2PfRPkUYXAI1W0rGyKh89P8kXEJyRyA+Mj7fXZ2/bGuTfGo75W\n        pE9baI08tiO5k0XKN4OSGzJXU2IkZ/bGzn4u5ektG/XgyZB93AlEMJVQmexrqzVYSoqq2vmEW8cY8Dlp\n        E+SiarwW1RxZDP8sfzyRUeLXWokEHjuvpNrY7nNvnNcWfTFeW2/7WuHxQXtku5HcyfWR3OcsiORFK3dH\n        cmZvbOUFauXpzRuhXrw6O15hlDzuqAcwq5ESgX+rpPD2XG8lhtpsiUDv4e3BF8c3G7hvTi7eFh4nKrAj\n        u+iN80iMR3ytIMm8vxcKzzN8An0WvXMSsqOcC/h1jdmao9ta8pxxe47t8+Balac3LqhRTzIKryaOB1iV\n        A/TNqR8t0kGNL1tFVrGqonhRcOEbfrhfW3hfFj1jpZ9FfobRZG61S3tvnEdiPOqrk32RNg9koVb71ubc\n        mpNQW+RfCkL6wwYWbhejOeNtcmzYy9Ox6BpeiRzZ0g5przavP0mywjl+Jkf+hPDKewRfDBKWRdC/squS\n        gmyJ7NW1hPv5PUX212e3CbePxlh2NIr3RWx0oc2D8InPXN/bEKKyy5Z20bpe2UdzRm332rfy9LUXSZYV\n        ZQ/dzBfPK6zbqRjc35OqOkYoUUjurBK8A3Dd0YL6IoPum+1HyHcO/Nc8ZPP5yJbIXl1L8LfyOfv3xnk0\n        xmqLRsj3O8nj4ycGxia+Tu+chNqiCj+V+P1ka92vJ2fUFiU9eToW3UCB8sXLBWCHEzg9JTKgasd1JQnO\n        Ve3VNqnsLT9QL14FkYLpG88DLFsie3UtIQaMm35m/944Y1ObkRijEXxTVWJcfKmO6GIkd0DtuN5CbRD3\n        93jkxhvJGbWpxta1xO1j0Q1wjBvpvUEwAU9OifYJk/JKRz9sCoJPzBeNCsL9tCitKpVPLUQS9KD5ZT/G\n        ks3nJFviSbmH5pTzqfr3xnkkxiO+OloHF/GqfMx8cUZyR9dyAzncr/INtfr15Izs1T168vTQxgOChM5C\n        j2xXHlkeiS8aiwgsgmw9T+RciC2qzSDbGXEe8dXxmFSb5CNQkRhdf9aMfh7jUfbG3svTp9t4Z6OnW1Y2\n        BdPRYmiDOp7QtNuC63ttPpIRX58Rnvaa3ywOj8z7iL/jXVw8AxQUnnhswvN5efkf+nnqL5jaAGcAAAAA\n        SUVORK5CYII=\n</value>\n  </data>\n  <metadata name=\"toolTip.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>17, 17</value>\n  </metadata>\n  <metadata name=\"toolTipManual.TrayLocation\" type=\"System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\">\n    <value>107, 17</value>\n  </metadata>\n  <data name=\"textBoxDNS.Text\" xml:space=\"preserve\">\n    <value>一般可以直接用设备名连接到其他电脑。如果名称解析出错，可以手动指定 IP 地址映射。\n注意：如果电脑使用动态 IP 地址，那么每次对方 IP 变动时都要手动更改。</value>\n  </data>\n  <metadata name=\"$this.TrayHeight\" type=\"System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\">\n    <value>58</value>\n  </metadata>\n  <data name=\"$this.Icon\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n    <value>\n        AAABAAIAICAAAAAAGACoDAAAJgAAABAQAAAAABgAaAMAAM4MAAAoAAAAIAAAAEAAAAABABgAAAAAAAAM\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAEo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAEo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32FIv3Eo32AAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32EYv3Eo32AAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32BIf3GJD2Eov3Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAEo32CYn3GZD2DIf4Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        QZv0FI72GpH2FIv3Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32Con3HJH2FI72QJv0\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANJb1FI72GZD2Ho/2Eo32AAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAEo32Eo32G5H2FI72NJb1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAPpr0Fo72GZD2Don3Eo32AAAAAAAAAAAAAAAAAAAAAAAAEo32BIj3HJH2\n        Fo72Ppr0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAOpn0\n        Fo/2GZD2II/2Eo32AAAAAAAAAAAAAAAAEo32E432HJH2Fo/2Opn0AAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIo/2HJH2GZD2Foz3Eo32AAAAAAAAEo32\n        Cor3HJH2HJH2Io/2AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUZ7zA4f3Con3Con3Con3Con3\n        Con3Con3Con3DYv3HJH2HpL2HZH2GZD2GIz2Eo32Eo32C4v3HJH2HpL2HpL2HJH2DYv3Con3Con3Con3\n        Con3Con3Con3Con3AIX4Eo32WqLzD432Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2F4/2HZH2HpL2HpL2HZH2\n        EY32O5j0Npf0FI72HZH2HpL2HpL2HJH2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2Fo/2C4v3Eo32frPvSaPy\n        TqTyTqTyTqTyTqTyTqTyTqTyT6XyV6jxIJH2HZH2HpL2Eo32Opv0AAAAAAAALJT2FY/2HpL2HJH2K5T1\n        V6nxT6TyTqTyTqTyTqTyTqTyTqTyTqTyRqHzEo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZH2\n        GY72HZH2Eo32OJr0AAAAAAAAAAAAAAAAKZP1FY/2G5H2I5H2Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZH2Ho/2GpH2Eo32PZz0AAAAAAAAAAAAAAAAAAAA\n        AAAAL5b1FY/2GJD2KJT2Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAHZH2G472GZD2E432Npn0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKJL1Fo/2Fo/2J5P2Eo32AAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHZH2HpD2GJD2FI72MZj1AAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAJZL2Fo/2Fo/2KpT1Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAHZH2FIv3GZD2E472MZf1AAAAAAAABAQEBAQEAAAAAAAAAAAAAAAABAQEBAQEAAAAAAAA\n        JZL2Fo/2Fo/2H4/3Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32H5D2Doz2M5j0AAAA\n        AAAABAQEBAQEBAQEBAQEAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAJpL1D4z2J5T1Eo32AAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32NJj1AAAAAAAAAAAABAQE//jwBAQEBAQEAAAAAAAABAQE\n        //jwBAQEBAQEAAAAAAAAAAAAMJb1Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQE\n        AAAAAAAAAAAAAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////////////////////////////////v//f/x/\n        /j/4P/wf/B/4P/4P8H//B+D//4PB///Bg/8AAAAAAAAAAAABgAD/g8H//wfg//4P8H/8H/g/+DPMH/hh\n        hh/84Yc//+GH///zz/////////////////////////////////8oAAAAEAAAACAAAAABABgAAAAAAAAD\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32AAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEo32GJD2Eo32AAAAAAAAAAAAAAAAAAAA\n        AAAACYn3DIf4AAAAAAAAAAAAAAAAAAAAAAAANJb1GZD2Eo32AAAAAAAAAAAAAAAAEo32FI72AAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAOpn0GZD2Eo32AAAAAAAAE432Fo/2AAAAAAAAAAAAAAAAAAAAA4f3Con3\n        Con3Con3DYv3HpL2GZD2Eo32C4v3HpL2HJH2Con3Con3Con3Con3Eo32SaPyTqTyTqTyTqTyV6jxHZH2\n        Eo32AAAALJT2HpL2K5T1T6TyTqTyTqTyTqTyEo32AAAAAAAAAAAAAAAAHo/2Eo32AAAAAAAAAAAAL5b1\n        GJD2Eo32AAAAAAAAAAAAAAAAAAAAAAAAAAAAHpD2FI72AAAAAAAAAAAAAAAAAAAAJZL2Fo/2Eo32AAAA\n        AAAAAAAAAAAAAAAAEo32Doz2AAAABAQEBAQEAAAABAQEBAQEAAAAJpL1J5T1AAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAABAQEBAQEAAAABAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n        AAAAAAAA//8AAP//AAD//wAA7/8AAMfnAADjzwAA8Z8AAAAAAAABAAAA848AAOfHAADJJwAA+T8AAP//\n        AAD//wAA//8AAA==\n</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmMessage.Designer.cs",
    "content": "﻿namespace MouseWithoutBorders\n{\n    partial class FrmMessage\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmMessage));\n            this.labelTitle = new System.Windows.Forms.Label();\n            this.textExtraInfo = new System.Windows.Forms.TextBox();\n            this.timerLife = new System.Windows.Forms.Timer(this.components);\n            this.labelLifeTime = new System.Windows.Forms.Label();\n            this.textBoxMessage = new System.Windows.Forms.TextBox();\n            this.pictureBoxIcon = new System.Windows.Forms.PictureBox();\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxIcon)).BeginInit();\n            this.SuspendLayout();\n            // \n            // labelTitle\n            // \n            this.labelTitle.AutoSize = true;\n            this.labelTitle.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.labelTitle.Location = new System.Drawing.Point(21, 0);\n            this.labelTitle.Name = \"labelTitle\";\n            this.labelTitle.Size = new System.Drawing.Size(168, 16);\n            this.labelTitle.TabIndex = 0;\n            this.labelTitle.Text = \"无界鼠标\";\n            // \n            // textExtraInfo\n            // \n            this.textExtraInfo.BackColor = System.Drawing.SystemColors.Info;\n            this.textExtraInfo.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.textExtraInfo.Dock = System.Windows.Forms.DockStyle.Bottom;\n            this.textExtraInfo.Enabled = false;\n            this.textExtraInfo.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 63.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.textExtraInfo.Location = new System.Drawing.Point(0, 161);\n            this.textExtraInfo.Margin = new System.Windows.Forms.Padding(20);\n            this.textExtraInfo.Multiline = true;\n            this.textExtraInfo.Name = \"textExtraInfo\";\n            this.textExtraInfo.ReadOnly = true;\n            this.textExtraInfo.Size = new System.Drawing.Size(720, 239);\n            this.textExtraInfo.TabIndex = 3;\n            this.textExtraInfo.Text = \"???\\r\\nLLL\";\n            this.textExtraInfo.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;\n            // \n            // timerLife\n            // \n            this.timerLife.Enabled = true;\n            this.timerLife.Interval = 1000;\n            this.timerLife.Tick += new System.EventHandler(this.TimerLife_Tick);\n            // \n            // labelLifeTime\n            // \n            this.labelLifeTime.AutoSize = true;\n            this.labelLifeTime.Dock = System.Windows.Forms.DockStyle.Right;\n            this.labelLifeTime.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 9.75F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.labelLifeTime.Location = new System.Drawing.Point(720, 0);\n            this.labelLifeTime.Name = \"labelLifeTime\";\n            this.labelLifeTime.Size = new System.Drawing.Size(0, 16);\n            this.labelLifeTime.TabIndex = 4;\n            // \n            // textBoxMessage\n            // \n            this.textBoxMessage.BackColor = System.Drawing.SystemColors.Info;\n            this.textBoxMessage.BorderStyle = System.Windows.Forms.BorderStyle.None;\n            this.textBoxMessage.Dock = System.Windows.Forms.DockStyle.Fill;\n            this.textBoxMessage.Enabled = false;\n            this.textBoxMessage.Font = new System.Drawing.Font(\"Microsoft Sans Serif\", 20.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));\n            this.textBoxMessage.Location = new System.Drawing.Point(0, 0);\n            this.textBoxMessage.Margin = new System.Windows.Forms.Padding(20);\n            this.textBoxMessage.Multiline = true;\n            this.textBoxMessage.Name = \"textBoxMessage\";\n            this.textBoxMessage.ReadOnly = true;\n            this.textBoxMessage.Size = new System.Drawing.Size(720, 400);\n            this.textBoxMessage.TabIndex = 2;\n            this.textBoxMessage.Text = \"Message Text\";\n            this.textBoxMessage.TextAlign = System.Windows.Forms.HorizontalAlignment.Center;\n            // \n            // pictureBoxIcon\n            // \n            this.pictureBoxIcon.Image = ((System.Drawing.Image)(resources.GetObject(\"pictureBoxIcon.Image\")));\n            this.pictureBoxIcon.Location = new System.Drawing.Point(0, 0);\n            this.pictureBoxIcon.Name = \"pictureBoxIcon\";\n            this.pictureBoxIcon.Size = new System.Drawing.Size(16, 16);\n            this.pictureBoxIcon.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;\n            this.pictureBoxIcon.TabIndex = 5;\n            this.pictureBoxIcon.TabStop = false;\n            // \n            // frmMessage\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(255)))), ((int)(((byte)(255)))), ((int)(((byte)(231)))));\n            this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;\n            this.ClientSize = new System.Drawing.Size(720, 400);\n            this.Controls.Add(this.pictureBoxIcon);\n            this.Controls.Add(this.labelLifeTime);\n            this.Controls.Add(this.textExtraInfo);\n            this.Controls.Add(this.labelTitle);\n            this.Controls.Add(this.textBoxMessage);\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.Name = \"frmMessage\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;\n            this.Text = \"frmMessage\";\n            this.TopMost = true;\n            this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.FrmMessage_FormClosed);\n            ((System.ComponentModel.ISupportInitialize)(this.pictureBoxIcon)).EndInit();\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Label labelTitle;\n        private System.Windows.Forms.TextBox textExtraInfo;\n        private System.Windows.Forms.Timer timerLife;\n        private System.Windows.Forms.Label labelLifeTime;\n        private System.Windows.Forms.TextBox textBoxMessage;\n        private System.Windows.Forms.PictureBox pictureBoxIcon;\n    }\n}"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmScreen.Designer.cs",
    "content": "﻿namespace MouseWithoutBorders\n{\n    partial class FrmScreen\n    {\n        /// <summary>\n        /// Required designer variable.\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// Clean up any resources being used.\n        /// </summary>\n        /// <param name=\"disposing\">true if managed resources should be disposed; otherwise, false.</param>\n        protected override void Dispose(bool disposing)\n        {\n            if (disposing && (components != null))\n            {\n                components.Dispose();\n            }\n            base.Dispose(disposing);\n        }\n\n        #region Windows Form Designer generated code\n\n        /// <summary>\n        /// Required method for Designer support - do not modify\n        /// the contents of this method with the code editor.\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.components = new System.ComponentModel.Container();\n            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FrmScreen));\n            this.MainMenu = new System.Windows.Forms.ContextMenuStrip(this.components);\n            this.menuExit = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();\n            this.menuAbout = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuHelp = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuGenDumpFile = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();\n            this.menuGetScreenCapture = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuGetFromAll = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuSendScreenCapture = new System.Windows.Forms.ToolStripMenuItem();\n            this.allToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuSend2Myself = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem1 = new System.Windows.Forms.ToolStripSeparator();\n            this.menuWindowsPhone = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuWindowsPhoneEnable = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuWindowsPhoneDownload = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuWindowsPhoneInformation = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuReinstallKeyboardAndMouseHook = new System.Windows.Forms.ToolStripMenuItem();\n            this.menuMachineMatrix = new System.Windows.Forms.ToolStripMenuItem();\n            this.toolStripMenuItem2 = new System.Windows.Forms.ToolStripSeparator();\n            this.MenuAllPC = new System.Windows.Forms.ToolStripMenuItem();\n            this.dUCTDOToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.tRUONG2DToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();\n            this.NotifyIcon = new System.Windows.Forms.NotifyIcon(this.components);\n            this.picLogonLogo = new System.Windows.Forms.PictureBox();\n            this.MainMenu.SuspendLayout();\n            ((System.ComponentModel.ISupportInitialize)(this.picLogonLogo)).BeginInit();\n            this.SuspendLayout();\n            // \n            // MainMenu\n            // \n            this.MainMenu.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.menuExit,\n            this.toolStripSeparator2,\n            this.menuAbout,\n            this.menuHelp,\n            this.menuGenDumpFile,\n            this.toolStripSeparator1,\n            this.menuGetScreenCapture,\n            this.menuSendScreenCapture,\n            this.toolStripMenuItem1,\n            this.menuWindowsPhone,\n            this.menuReinstallKeyboardAndMouseHook,\n            this.menuMachineMatrix,\n            this.toolStripMenuItem2,\n            this.MenuAllPC,\n            this.dUCTDOToolStripMenuItem,\n            this.tRUONG2DToolStripMenuItem});\n            this.MainMenu.Name = \"MainMenu\";\n            this.MainMenu.Size = new System.Drawing.Size(197, 292);\n            this.MainMenu.Opening += new System.ComponentModel.CancelEventHandler(this.MainMenu_Opening);\n            this.MainMenu.MouseLeave += new System.EventHandler(this.MainMenu_MouseLeave);\n            // \n            // menuExit\n            // \n            this.menuExit.ForeColor = System.Drawing.Color.Black;\n            this.menuExit.Name = \"menuExit\";\n            this.menuExit.Size = new System.Drawing.Size(196, 22);\n            this.menuExit.Text = \"退出(&E)\";\n            this.menuExit.Click += new System.EventHandler(this.MenuExit_Click);\n            // \n            // toolStripSeparator2\n            // \n            this.toolStripSeparator2.Name = \"toolStripSeparator2\";\n            this.toolStripSeparator2.Size = new System.Drawing.Size(193, 6);\n            // \n            // menuAbout\n            // \n            this.menuAbout.ForeColor = System.Drawing.Color.Black;\n            this.menuAbout.Name = \"menuAbout\";\n            this.menuAbout.Size = new System.Drawing.Size(196, 22);\n            this.menuAbout.Text = \"关于(&B)\";\n            this.menuAbout.Click += new System.EventHandler(this.MenuAbout_Click);\n            // \n            // menuHelp\n            // \n            this.menuHelp.Name = \"menuHelp\";\n            this.menuHelp.Size = new System.Drawing.Size(196, 22);\n            this.menuHelp.Text = \"帮助(&H)\";\n            this.menuHelp.Click += new System.EventHandler(this.MenuHelp_Click);\n            // \n            // menuGenDumpFile\n            // \n            this.menuGenDumpFile.Name = \"menuGenDumpFile\";\n            this.menuGenDumpFile.Size = new System.Drawing.Size(196, 22);\n            this.menuGenDumpFile.Text = \"运行日志(&G)\";\n            this.menuGenDumpFile.ToolTipText = \"创建用于分析问题的日志文件，日志文件将在程序目录下生成。\";\n            this.menuGenDumpFile.Visible = false;\n            this.menuGenDumpFile.Click += new System.EventHandler(this.MenuGenDumpFile_Click);\n            // \n            // toolStripSeparator1\n            // \n            this.toolStripSeparator1.Name = \"toolStripSeparator1\";\n            this.toolStripSeparator1.Size = new System.Drawing.Size(193, 6);\n            // \n            // menuGetScreenCapture\n            // \n            this.menuGetScreenCapture.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.menuGetFromAll});\n            this.menuGetScreenCapture.ForeColor = System.Drawing.Color.Black;\n            this.menuGetScreenCapture.Name = \"menuGetScreenCapture\";\n            this.menuGetScreenCapture.Size = new System.Drawing.Size(196, 22);\n            this.menuGetScreenCapture.Text = \"获取截屏自(&G)\";\n            // \n            // menuGetFromAll\n            // \n            this.menuGetFromAll.Enabled = false;\n            this.menuGetFromAll.Name = \"menuGetFromAll\";\n            this.menuGetFromAll.Size = new System.Drawing.Size(85, 22);\n            this.menuGetFromAll.Text = \"所有电脑\";\n            this.menuGetFromAll.Click += new System.EventHandler(this.MenuGetScreenCaptureClick);\n            // \n            // menuSendScreenCapture\n            // \n            this.menuSendScreenCapture.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {\n            this.allToolStripMenuItem,\n            this.menuSend2Myself});\n            this.menuSendScreenCapture.ForeColor = System.Drawing.Color.Black;\n            this.menuSendScreenCapture.Name = \"menuSendScreenCapture\";\n            this.menuSendScreenCapture.Size = new System.Drawing.Size(196, 22);\n            this.menuSendScreenCapture.Text = \"发送截屏到(&C)\";\n            // \n            // allToolStripMenuItem\n            // \n            this.allToolStripMenuItem.Name = \"allToolStripMenuItem\";\n            this.allToolStripMenuItem.Size = new System.Drawing.Size(105, 22);\n            this.allToolStripMenuItem.Text = \"所有电脑\";\n            this.allToolStripMenuItem.Click += new System.EventHandler(this.MenuSendScreenCaptureClick);\n            // \n            // menuSend2Myself\n            // \n            this.menuSend2Myself.Name = \"menuSend2Myself\";\n            this.menuSend2Myself.Size = new System.Drawing.Size(105, 22);\n            this.menuSend2Myself.Text = \"此电脑\";\n            this.menuSend2Myself.Click += new System.EventHandler(this.MenuSendScreenCaptureClick);\n            // \n            // toolStripMenuItem1\n            // \n            this.toolStripMenuItem1.Name = \"toolStripMenuItem1\";\n            this.toolStripMenuItem1.Size = new System.Drawing.Size(193, 6);\n            // \n            // menuReinstallKeyboardAndMouseHook\n            // \n            this.menuReinstallKeyboardAndMouseHook.Name = \"menuReinstallKeyboardAndMouseHook\";\n            this.menuReinstallKeyboardAndMouseHook.Size = new System.Drawing.Size(196, 22);\n            this.menuReinstallKeyboardAndMouseHook.Text = \"重新安装快捷键侦听器(&R)\";\n            this.menuReinstallKeyboardAndMouseHook.ToolTipText = \"This might help when keyboard/Mouse redirection stops working\";\n            this.menuReinstallKeyboardAndMouseHook.Visible = false;\n            this.menuReinstallKeyboardAndMouseHook.Click += new System.EventHandler(this.MenuReinstallKeyboardAndMouseHook_Click);\n            // \n            // menuMachineMatrix\n            // \n            this.menuMachineMatrix.Font = new System.Drawing.Font(System.Windows.Forms.Control.DefaultFont.Name, System.Windows.Forms.Control.DefaultFont.Size, System.Drawing.FontStyle.Bold);\n            this.menuMachineMatrix.ForeColor = System.Drawing.Color.Black;\n            this.menuMachineMatrix.Name = \"menuMachineMatrix\";\n            this.menuMachineMatrix.Size = new System.Drawing.Size(196, 22);\n            this.menuMachineMatrix.Text = \"设置(&S)\";\n            this.menuMachineMatrix.Click += new System.EventHandler(this.MenuMachineMatrix_Click);\n            // \n            // toolStripMenuItem2\n            // \n            this.toolStripMenuItem2.Name = \"toolStripMenuItem2\";\n            this.toolStripMenuItem2.Size = new System.Drawing.Size(193, 6);\n            // \n            // menuAllPC\n            // \n            this.MenuAllPC.CheckOnClick = true;\n            this.MenuAllPC.Name = \"menuAllPC\";\n            this.MenuAllPC.Size = new System.Drawing.Size(196, 22);\n            this.MenuAllPC.Text = \"所有电脑(&A)\";\n            this.MenuAllPC.ToolTipText = \"Repeat Mouse/keyboard in all machines.\";\n            this.MenuAllPC.Click += new System.EventHandler(this.MenuAllPC_Click);\n            // \n            // dUCTDOToolStripMenuItem\n            // \n            this.dUCTDOToolStripMenuItem.Name = \"dUCTDOToolStripMenuItem\";\n            this.dUCTDOToolStripMenuItem.Size = new System.Drawing.Size(196, 22);\n            this.dUCTDOToolStripMenuItem.Tag = \"MACHINE: TEST1\";\n            this.dUCTDOToolStripMenuItem.Text = \"DUCTDO\";\n            // \n            // tRUONG2DToolStripMenuItem\n            // \n            this.tRUONG2DToolStripMenuItem.Name = \"tRUONG2DToolStripMenuItem\";\n            this.tRUONG2DToolStripMenuItem.Size = new System.Drawing.Size(196, 22);\n            this.tRUONG2DToolStripMenuItem.Tag = \"MACHINE: TEST2\";\n            this.tRUONG2DToolStripMenuItem.Text = \"TRUONG2D\";\n            // \n            // notifyIcon\n            // \n            this.NotifyIcon.BalloonTipIcon = System.Windows.Forms.ToolTipIcon.Info;\n            this.NotifyIcon.BalloonTipText = \"Microsoft® Visual Studio® 2010\";\n            this.NotifyIcon.BalloonTipTitle = \"Microsoft® Visual Studio® 2010\";\n            this.NotifyIcon.ContextMenuStrip = this.MainMenu;\n            this.NotifyIcon.Icon = ((System.Drawing.Icon)(resources.GetObject(\"notifyIcon.Icon\")));\n            this.NotifyIcon.Text = \"Microsoft® Visual Studio® 2010\";\n            this.NotifyIcon.MouseDown += new System.Windows.Forms.MouseEventHandler(this.NotifyIcon_MouseDown);\n            // \n            // picLogonLogo\n            // \n            this.picLogonLogo.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;\n            this.picLogonLogo.Image = global::MouseWithoutBorders.Properties.Images.MouseWithoutBorders;\n            this.picLogonLogo.Location = new System.Drawing.Point(99, 62);\n            this.picLogonLogo.Name = \"picLogonLogo\";\n            this.picLogonLogo.Size = new System.Drawing.Size(95, 17);\n            this.picLogonLogo.TabIndex = 1;\n            this.picLogonLogo.TabStop = false;\n            this.picLogonLogo.Visible = false;\n            // \n            // frmScreen\n            // \n            this.AllowDrop = true;\n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.BackColor = System.Drawing.Color.Black;\n            this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;\n            this.ClientSize = new System.Drawing.Size(10, 10);\n            this.ControlBox = false;\n            this.Controls.Add(this.picLogonLogo);\n            this.Cursor = System.Windows.Forms.Cursors.Default;\n            this.Enabled = false;\n            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;\n            this.Icon = ((System.Drawing.Icon)(resources.GetObject(\"$this.Icon\")));\n            this.MaximizeBox = false;\n            this.MinimizeBox = false;\n            this.Name = \"frmScreen\";\n            this.Opacity = 0.5D;\n            this.ShowIcon = false;\n            this.ShowInTaskbar = false;\n            this.StartPosition = System.Windows.Forms.FormStartPosition.Manual;\n            this.Text = \"Microsoft® Visual Studio® 2010 Application\";\n            this.TopMost = true;\n            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.FrmScreen_FormClosing);\n            this.Load += new System.EventHandler(this.FrmScreen_Load);\n            this.Shown += new System.EventHandler(this.FrmScreen_Shown);\n            this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FrmScreen_MouseMove);\n            this.MainMenu.ResumeLayout(false);\n            ((System.ComponentModel.ISupportInitialize)(this.picLogonLogo)).EndInit();\n            this.ResumeLayout(false);\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.ToolStripMenuItem menuExit;\n        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem1;\n        private System.Windows.Forms.ToolStripMenuItem menuMachineMatrix;\n        private System.Windows.Forms.ToolStripSeparator toolStripMenuItem2;\n        private System.Windows.Forms.ToolStripMenuItem dUCTDOToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem tRUONG2DToolStripMenuItem;\n        private System.Windows.Forms.ToolStripMenuItem menuSendScreenCapture;\n        private System.Windows.Forms.ToolStripMenuItem menuSend2Myself;\n        private System.Windows.Forms.ToolStripMenuItem menuGetScreenCapture;\n        private System.Windows.Forms.ToolStripMenuItem menuGetFromAll;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;\n        private System.Windows.Forms.ToolStripMenuItem allToolStripMenuItem;\n        private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;\n        private System.Windows.Forms.ToolStripMenuItem menuAbout;\n        private System.Windows.Forms.PictureBox picLogonLogo;\n        private System.Windows.Forms.ToolStripMenuItem menuHelp;\n        private System.Windows.Forms.ToolStripMenuItem menuReinstallKeyboardAndMouseHook;\n        private System.Windows.Forms.ToolStripMenuItem menuGenDumpFile;\n        private System.Windows.Forms.ToolStripMenuItem menuWindowsPhone;\n        private System.Windows.Forms.ToolStripMenuItem menuWindowsPhoneEnable;\n        private System.Windows.Forms.ToolStripMenuItem menuWindowsPhoneInformation;\n        private System.Windows.Forms.ToolStripMenuItem menuWindowsPhoneDownload;\n    }\n}\n\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Form/frmScreen.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Diagnostics.CodeAnalysis;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Windows.Forms;\n\nusing Microsoft.PowerToys.Telemetry;\n\n// <summary>\n//     Startup/main form + helper methods.\n// </summary>\n// <history>\n//     2008 created by Truong Do (ductdo).\n//     2009-... modified by Truong Do (TruongDo).\n//     2023- Included in PowerToys.\n// </history>\nusing MouseWithoutBorders.Class;\nusing MouseWithoutBorders.Core;\nusing MouseWithoutBorders.Properties;\n\nusing Timer = System.Windows.Forms.Timer;\n\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#ShowMouseWithoutBordersUiOnWinLogonDesktop(System.Boolean)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#ChangeIcon(System.Int32)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#UpdateMenu(MouseWithoutBorders.MachineInf[])\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#frmScreen_Load(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#MenuNewVersion(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#.ctor()\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#LoadPlugins()\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Design\", \"CA1031:DoNotCatchGeneralExceptionTypes\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#menuPersonalizeLogonScrPluginClick(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1304:SpecifyCultureInfo\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)\", MessageId = \"System.String.ToLower\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Maintainability\", \"CA1502:AvoidExcessiveComplexity\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Performance\", \"CA1814:PreferJaggedArraysOverMultidimensional\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#LogonLogo\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Performance\", \"CA1814:PreferJaggedArraysOverMultidimensional\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#frmScreen_Load(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Performance\", \"CA1800:DoNotCastUnnecessarily\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#LoadNewLogonBackground()\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Performance\", \"CA1800:DoNotCastUnnecessarily\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#UncheckAllMenus()\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Usage\", \"CA1806:DoNotIgnoreMethodResults\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#WndProc(System.Windows.Forms.Message&)\", MessageId = \"MouseWithoutBorders.NativeMethods.SendMessage(System.IntPtr,System.Int32,System.IntPtr,System.IntPtr)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Usage\", \"CA1806:DoNotIgnoreMethodResults\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#Destroy()\", MessageId = \"MouseWithoutBorders.NativeMethods.SendMessage(System.IntPtr,System.Int32,System.IntPtr,System.IntPtr)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Usage\", \"CA1806:DoNotIgnoreMethodResults\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#helperTimer_Tick(System.Object,System.EventArgs)\", MessageId = \"MouseWithoutBorders.NativeMethods.SendMessage(System.IntPtr,System.Int32,System.IntPtr,System.IntPtr)\", Justification = \"Dotnet port with style preservation\")]\n[module: SuppressMessage(\"Microsoft.Globalization\", \"CA1300:SpecifyMessageBoxOptions\", Scope = \"member\", Target = \"MouseWithoutBorders.frmScreen.#menuPersonalizeLogonScrPluginClick(System.Object,System.EventArgs)\", Justification = \"Dotnet port with style preservation\")]\n\nnamespace MouseWithoutBorders\n{\n    internal partial class FrmScreen : System.Windows.Forms.Form\n    {\n#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager\n        private Cursor dotCur;\n        private Cursor dropCur;\n        private int[,] logonLogo;\n        private Timer helperTimer;\n#pragma warning restore CA2213\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal int CurIcon { get; set; }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal NotifyIcon NotifyIcon { get; set; }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal System.Windows.Forms.ToolStripMenuItem MenuAllPC { get; set; }\n\n        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]\n        internal System.Windows.Forms.ContextMenuStrip MainMenu { get; set; }\n\n        internal FrmScreen()\n        {\n            InitializeComponent();\n            Text = Setting.Values.MyID;\n            NotifyIcon.BalloonTipText = Application.ProductName;\n            NotifyIcon.BalloonTipTitle = Application.ProductName;\n            menuGenDumpFile.Visible = true;\n\n            Common.WndProcCounter++;\n\n            try\n            {\n                menuWindowsPhone.Visible = false; // No longer supported.\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        private void FrmScreen_FormClosing(object sender, FormClosingEventArgs e)\n        {\n            if (e.CloseReason != CloseReason.WindowsShutDown)\n            {\n                if (Tag == null)\n                {\n                    e.Cancel = true;\n                }\n            }\n            else\n            {\n                Common.StartServiceAndSendLogoffSignal();\n                Quit(true, true);\n            }\n        }\n\n        internal void Destroy()\n        {\n            if (helperTimer != null)\n            {\n                helperTimer.Stop();\n                helperTimer.Dispose();\n                helperTimer = null;\n            }\n\n            NotifyIcon.Visible = false;\n            NotifyIcon.Dispose();\n            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n            {\n                Common.RunDDHelper(true);\n            }\n\n            // Common.UnhookClipboard();\n            Tag = \"此电脑\";\n            Close();\n        }\n\n        internal void Quit(bool cleanup, bool isFormClosing)\n        {\n            Tag = \"Quitting...\";\n\n            Setting.Values.SwitchCount += Common.SwitchCount;\n            Process me = Process.GetCurrentProcess();\n            Common.WndProcCounter++;\n\n            try\n            {\n                if (cleanup)\n                {\n                    Common.Cleanup();\n                }\n\n                Common.WndProcCounter++;\n                if (!Common.RunOnScrSaverDesktop)\n                {\n                    Common.ReleaseAllKeys();\n                }\n\n                Common.RunDDHelper(true);\n            }\n            catch (Exception e)\n            {\n                _ = MessageBox.Show(e.ToString());\n            }\n\n            Common.MMSleep(1);\n\n            Application.Exit();\n            me.KillProcess();\n        }\n\n        private void MenuExit_Click(object sender, EventArgs e)\n        {\n            PowerToysTelemetry.Log.WriteEvent(new MouseWithoutBorders.Telemetry.MouseWithoutBordersOldUIQuitEvent());\n\n            Quit(true, false);\n        }\n\n        internal void MenuOnClick(object sender, EventArgs e)\n        {\n            string name = (sender as ToolStripMenuItem).Text;\n            Common.SwitchToMachine(name);\n        }\n\n        internal void UpdateMenu()\n        {\n            try\n            {\n                ChangeIcon(-1);\n                while (MainMenu.Items[MainMenu.Items.Count - 1].Tag != null &&\n                    ((string)MainMenu.Items[MainMenu.Items.Count - 1].Tag).StartsWith(\"MACHINE: \", StringComparison.CurrentCultureIgnoreCase))\n                {\n                    MainMenu.Items.Remove(MainMenu.Items[MainMenu.Items.Count - 1]);\n                }\n\n                while (!menuSendScreenCapture.DropDown.Items[\n                    menuSendScreenCapture.DropDown.Items.Count - 1].Text.Equals(\"此电脑\", StringComparison.OrdinalIgnoreCase))\n                {\n                    menuSendScreenCapture.DropDown.Items.Remove(menuSendScreenCapture.DropDown.Items[\n                        menuSendScreenCapture.DropDown.Items.Count - 1]);\n                }\n\n                while (!menuGetScreenCapture.DropDown.Items[\n                    menuGetScreenCapture.DropDown.Items.Count - 1].Text.Equals(\"所有电脑\", StringComparison.OrdinalIgnoreCase))\n                {\n                    menuGetScreenCapture.DropDown.Items.Remove(menuGetScreenCapture.DropDown.Items[\n                        menuGetScreenCapture.DropDown.Items.Count - 1]);\n                }\n\n                for (int i = 0; i < Common.MAX_MACHINE; i++)\n                {\n                    string newMachine = Common.MachineMatrix[i].Trim();\n\n                    if (Common.MachinePool.TryFindMachineByName(newMachine, out MachineInf inf) && MachinePool.IsAlive(inf))\n                    {\n                        ToolStripMenuItem newItem = new(\n                            newMachine,\n                            null,\n                            new EventHandler(MenuOnClick));\n                        newItem.Tag = \"MACHINE: \" + inf.Name;\n                        newItem.ToolTipText = \"Switch Mouse/keyboard to \" + newMachine;\n                        newItem.Visible = true;\n                        _ = MainMenu.Items.Add(newItem);\n\n                        if (!newMachine.Equals(Common.MachineName.Trim(), StringComparison.OrdinalIgnoreCase))\n                        {\n                            ToolStripMenuItem newItem2 = new(\n                                inf.Name.Trim(),\n                                null,\n                                new EventHandler(MenuSendScreenCaptureClick));\n                            newItem2.Visible = true;\n                            _ = menuSendScreenCapture.DropDown.Items.Add(newItem2);\n\n                            ToolStripMenuItem newItem3 = new(\n                                inf.Name.Trim(),\n                                null,\n                                new EventHandler(MenuGetScreenCaptureClick));\n                            newItem3.Visible = true;\n                            _ = menuGetScreenCapture.DropDown.Items.Add(newItem3);\n                        }\n                    }\n                }\n\n                menuGetScreenCapture.DropDown.Items[0].Enabled = menuGetScreenCapture.DropDown.Items.Count > 1;\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        // We dont do something heavy in our timer\n        private void FrmScreen_Load(object sender, EventArgs e)\n        {\n            try\n            {\n                // Common.UpdateMenu();\n                // Common.HookClipboard();\n                CurIcon = Common.ICON_ONE;\n                ChangeIcon(-1);\n                dotCur = CustomCursor.CreateDotCursor();\n                Cursor = dotCur;\n                dropCur = CustomCursor.CreateCursor(Icon.ToBitmap(), 0, 0);\n                BackColor = Color.White;\n                Opacity = 0.15;\n                UpdateNotifyIcon();\n\n                if (picLogonLogo.Image != null)\n                {\n                    Bitmap b = new(picLogonLogo.Image);\n                    logonLogo = new int[b.Width, b.Height];\n\n                    for (int i = 0; i < b.Width; i++)\n                    {\n                        for (int j = 0; j < b.Height; j++)\n                        {\n                            Color c = b.GetPixel(i, j);\n                            logonLogo[i, j] = !(c.G == 255 && c.R == 0 && c.B == 0) ? (c.B << 16) | (c.G << 8) | c.R : -1;\n                        }\n                    }\n\n                    b.Dispose();\n                }\n            }\n            catch (Exception ex)\n            {\n                BackColor = Color.White;\n                Opacity = 0.15;\n                Logger.Log(ex);\n            }\n\n            helperTimer = new System.Windows.Forms.Timer();\n            helperTimer.Interval = 100;\n            helperTimer.Tick += new EventHandler(HelperTimer_Tick);\n            helperTimer.Start();\n            Common.WndProcCounter++;\n\n            if (Environment.OSVersion.Version.Major > 6 ||\n                   (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1))\n            {\n                // Win7 up\n                _ = NativeMethods.ChangeWindowMessageFilterEx(Handle, NativeMethods.WM_SHOW_SETTINGS_FORM, 1, IntPtr.Zero);\n            }\n        }\n\n        private long count = 21;\n\n        // private bool checkForNewVersion;\n#if USING_FORM\n        private static frmLogon fLogon = null;\n#endif\n        private bool busy;\n        private bool shownSetupFormOneTime;\n        private bool myDesktopNotActive;\n\n        private void HelperTimer_Tick(object sender, EventArgs e)\n        {\n            Common.WndProcCounter++;\n\n            if (busy)\n            {\n                return;\n            }\n\n            busy = true;\n\n            try\n            {\n                if (!Common.IsMyDesktopActive() || Common.CurrentProcess.SessionId != NativeMethods.WTSGetActiveConsoleSessionId())\n                {\n                    myDesktopNotActive = true;\n\n                    SocketStuff sk = Common.Sk;\n\n                    // We are not on application desktop\n                    if (sk != null)\n                    {\n                        turnedOff = true;\n                        Common.SecondOpenSocketTry = false;\n                        sk.Close(false);\n                        Common.Sk = null;\n                        count = 21;\n#if USING_FORM\n                        if (fLogon != null) fLogon.Hide();\n#endif\n\n                        if (Common.MainFormVisible)\n                        {\n                            Common.MainFormDot();\n                        }\n\n                        InputSimulation.ResetSystemKeyFlags();\n\n                        Common.DoSomethingInTheInputCallbackThread(() =>\n                        {\n                            Common.Hook?.ResetLastSwitchKeys();\n                        });\n\n                        Common.CheckForDesktopSwitchEvent(true);\n                    }\n                }\n                else\n                {\n                    if (Common.Sk == null)\n                    {\n                        if (!Common.SecondOpenSocketTry)\n                        {\n                            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && !Common.GetUserName())\n                            {\n                                // While Windows 8 is hybrid-shutting down, user name would be empty (as returned from the .Net API), we should not do anything in this case.\n                                Logger.LogDebug(\"No active user.\");\n                                Thread.Sleep(1000);\n                                busy = false;\n                                return;\n                            }\n\n                            if (myDesktopNotActive)\n                            {\n                                myDesktopNotActive = false;\n                                Common.MyKey = Setting.Values.MyKey;\n                            }\n\n                            Common.UpdateMachinePoolStringSetting();\n\n                            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && (Setting.Values.FirstRun || Common.KeyCorrupted))\n                            {\n                                if (!shownSetupFormOneTime)\n                                {\n                                    shownSetupFormOneTime = true;\n                                    Common.ShowMachineMatrix();\n\n                                    if (Common.KeyCorrupted && !Setting.Values.FirstRun)\n                                    {\n                                        Common.KeyCorrupted = false;\n                                        string msg = \"连接密码意外损坏，请重新生成。\";\n                                        MessageBox.Show(msg, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Warning);\n                                    }\n                                }\n                            }\n                        }\n\n                        Common.ReopenSockets(false);\n                        Common.SecondOpenSocketTry = true;\n\n                        if (Common.Sk != null)\n                        {\n                            Common.SendHello();\n                            Common.SendHeartBeat();\n\n                            if (!Common.RunOnScrSaverDesktop && !Common.RunOnLogonDesktop)\n                            {\n                                NotifyIcon.Visible = false;\n                                NotifyIcon.Visible = Setting.Values.ShowOriginalUI;\n\n                                // Common.ReHookClipboard();\n                            }\n\n                            Common.RunDDHelper();\n                        }\n\n                        count = 0;\n\n                        Common.InitDone = true;\n#if SHOW_ON_WINLOGON\n                        if (Common.RunOnLogonDesktop)\n                        {\n                            ShowMouseWithoutBordersUiOnWinLogonDesktop(true);\n                        }\n#endif\n                    }\n\n                    if ((count % 2) == 0)\n                    {\n                        if (Common.PleaseReopenSocket == 10 || (Common.PleaseReopenSocket > 0 && count > 0 && count % 300 == 0))\n                        {\n                            if (!Common.AtLeastOneSocketEstablished() || Common.PleaseReopenSocket == 10)\n                            {\n                                Thread.Sleep(1000);\n                                if (Common.PleaseReopenSocket > 0)\n                                {\n                                    Common.PleaseReopenSocket--;\n                                }\n\n                                // Double check.\n                                if (!Common.AtLeastOneSocketEstablished())\n                                {\n                                    Common.GetMachineName();\n                                    Logger.LogDebug(\"Common.pleaseReopenSocket: \" + Common.PleaseReopenSocket.ToString(CultureInfo.InvariantCulture));\n                                    Common.ReopenSockets(false);\n                                    Common.NewDesMachineID = Common.DesMachineID = Common.MachineID;\n                                }\n                            }\n                            else\n                            {\n                                Common.PleaseReopenSocket = 0;\n                            }\n                        }\n\n                        if (Common.PleaseReopenSocket == Common.REOPEN_WHEN_HOTKEY)\n                        {\n                            Common.PleaseReopenSocket = 0;\n                            Common.ReopenSockets(true);\n                        }\n                        else if (Common.PleaseReopenSocket == Common.REOPEN_WHEN_WSAECONNRESET)\n                        {\n                            Common.PleaseReopenSocket = 0;\n                            Thread.Sleep(1000);\n                            Common.UpdateClientSockets(\"REOPEN_WHEN_WSAECONNRESET\");\n                        }\n\n                        if (Common.RunOnLogonDesktop)\n                        {\n                            PaintMyNameOnDesktop();\n                        }\n\n                        /*\n                        if (checkClipboard)\n                        {\n                            Common.CtrlC = -1;\n                            checkClipboard = false;\n                            Common.CheckClipboard();\n                        }\n                        else if (--Common.CtrlC == 0)//Giving some timeout from the time Ctrl+C\n                        {\n                            if ((Common.GetTick() - Common.LastClipboardEventTime > 5000) && Common.CheckClipboard())\n                            {\n                                Common.ReHookClipboard();\n                            }\n                        }\n                         * */\n                    }\n\n                    // One more time after 1/3 minutes (Sometimes XP has explorer started late)\n                    if (count == 600 || count == 1800)\n                    {\n                        Common.RunDDHelper();\n                    }\n\n                    if (count == 600)\n                    {\n                        if (!Common.GeneratedKey)\n                        {\n                            Common.MyKey = Setting.Values.MyKey;\n\n                            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                            {\n                                Common.ShowMachineMatrix();\n\n                                Common.MatrixForm?.UpdateKeyTextBox();\n\n                                Common.Sk?.Close(false);\n\n                                Common.ShowToolTip(\"连接密码不可以手动修改，必须点击生成按钮自动生成.\", 10000);\n                            }\n                        }\n                        else if (!Common.KeyCorrupted && !Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && !Setting.Values.FirstRun && Common.AtLeastOneSocketConnected())\n                        {\n                            int myKeyDaysToExpire = Setting.Values.MyKeyDaysToExpire;\n\n                            if (myKeyDaysToExpire <= 0)\n                            {\n                                Common.ShowMachineMatrix();\n\n                                Common.Sk?.Close(false);\n\n                                string msg = \"连接密码已过期，请重新生成.\";\n                                Common.ShowToolTip(msg, 10000);\n                            }\n                            else if (myKeyDaysToExpire <= 15)\n                            {\n                                Common.ShowToolTip($\"连接密码将在 {myKeyDaysToExpire} 天内过期! 请注意重新生成密码.\", 10000);\n                            }\n                        }\n                    }\n                }\n\n                if (count == 20)\n                {\n#if SHOW_ON_WINLOGON\n                    // if (Common.RunOnLogonDesktop) ShowMouseWithoutBordersUiOnWinLogonDesktop(false);\n#endif\n                    Common.CheckForDesktopSwitchEvent(true);\n                    Common.UpdateClientSockets(\"helperTimer_Tick\"); // Sockets may be closed by the remote host when both machines switch desktop at the same time.\n                }\n\n                count++;\n                if (count % 5 == 0)\n                {\n                    if (Common.RunOnLogonDesktop)\n                    {\n                        ShowMessageOnLogonDesktop(Common.DesMachineID != ID.ALL);\n                    }\n\n                    if (Common.ToggleIcons != null)\n                    {\n                        Common.ToggleIcon();\n                    }\n\n                    if (count % 20 == 0)\n                    {\n                        Logger.LogAll();\n\n                        // Need to review this code on why it is needed (moved from MoveToMyNeighbourIfNeeded(...))\n                        for (int i = 0; i < Common.MachineMatrix.Length; i++)\n                        {\n                            if (string.IsNullOrEmpty(Common.MachineMatrix[i]) && !Common.InMachineMatrix(Common.MachineName))\n                            {\n                                Common.MachineMatrix[i] = Common.MachineName;\n                            }\n                        }\n\n                        if (count % 600 == 0 && Common.Sk != null)\n                        {\n                            // Send out Heartbeat every 1 or 5 mins\n                            if (Setting.Values.BlockScreenSaver || count % 3000 == 0)\n                            {\n                                Common.SendAwakeBeat();\n                                Common.RemoveDeadMachines();\n\n                                // GC.Collect();\n                                // GC.WaitForPendingFinalizers();\n                            }\n\n                            Common.CloseAnUnusedSocket();\n                        }\n                    }\n                    else if ((count % 36005) == 0)\n                    {// One hour\n                        Common.SaveSwitchCount();\n\n                        int rv = 0;\n\n                        if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop && Common.IsMyDesktopActive() && (rv = Common.SendMessageToHelper(0x400, IntPtr.Zero, IntPtr.Zero)) <= 0)\n                        {\n                            Logger.TelemetryLogTrace($\"{Common.HELPER_FORM_TEXT} not found: {rv}\", SeverityLevel.Warning);\n                        }\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Logger.Log(ex);\n            }\n            finally\n            {\n                busy = false;\n            }\n        }\n\n        private void MenuMachineMatrix_Click(object sender, EventArgs e)\n        {\n            Common.ShowMachineMatrix();\n        }\n\n        private void FrmScreen_MouseMove(object sender, MouseEventArgs e)\n        {\n            if (!Common.IsDropping)\n            {\n                if (Cursor != dotCur)\n                {\n                    Cursor = dotCur;\n                    Refresh();\n\n                    // Application.DoEvents();\n                }\n            }\n        }\n\n        internal void ChangeIcon(int iconCode)\n        {\n            try\n            {\n                Graphics g;\n                Pen p;\n                Bitmap bm = Images.notify_default;\n\n                /*\n                if (curIcon == Common.ICON_ONE)\n                {\n                    string[] x = Common.MachineMatrix;\n                    Graphics g = Graphics.FromImage(bm);\n                    if (x != null)\n                    {\n                        for (int i = 0; i < Common.MAX_MACHINE; i++)\n                        {\n                            if (x[i].Trim().Length > 0) g.FillEllipse(\n                                #if DEBUG\n                                Brushes.White,\n                                #else\n                                Brushes.Salmon,\n                                #endif\n                                3 + (i % 2) * 16, 3 + (i / 2) * 16, 10, 10);\n                        }\n                    }\n                    g.Dispose();\n                }\n                */\n\n                if (CurIcon != Common.ICON_ONE)\n                {\n                    p = new Pen(Color.Red, 2);\n                    g = Graphics.FromImage(bm);\n                    g.DrawRectangle(p, 1, 1, bm.Width - 2, bm.Height - 2);\n                    g.Dispose();\n                }\n\n                if (iconCode == Common.ICON_SMALL_CLIPBOARD)\n                {\n                    g = Graphics.FromImage(bm);\n                    g.FillEllipse(Brushes.Blue, 8, 8, 16, 16);\n                    g.Dispose();\n                }\n                else if (iconCode == Common.ICON_BIG_CLIPBOARD)\n                {\n                    g = Graphics.FromImage(bm);\n                    g.FillEllipse(Brushes.Yellow, 8, 8, 16, 16);\n                    g.Dispose();\n                }\n                else if (iconCode == Common.ICON_ERROR)\n                {\n                    g = Graphics.FromImage(bm);\n                    g.FillEllipse(Brushes.Red, 8, 8, 16, 16);\n                    g.Dispose();\n                }\n\n#if DEBUG\n                p = new Pen(Color.White, 4);\n                g = Graphics.FromImage(bm);\n                g.DrawRectangle(p, 6, 6, bm.Width - 12, bm.Height - 12);\n                g.Dispose();\n                p.Dispose();\n#endif\n\n                Logger.LogDebug($\"Changing icon to {iconCode}.\");\n\n                if (NotifyIcon.Icon != null)\n                {\n                    NativeMethods.DestroyIcon(NotifyIcon.Icon.Handle);\n                }\n\n                NotifyIcon.Icon = Icon.FromHandle(bm.GetHicon());\n                bm.Dispose();\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        internal void MenuAllPC_Click(object sender, EventArgs e)\n        {\n            Logger.LogDebug(\"menuAllPC_Click\");\n            Common.SwitchToMultipleMode(MenuAllPC.Checked, true);\n            CurIcon = MenuAllPC.Checked ? Common.ICON_ALL : Common.ICON_ONE;\n            ChangeIcon(CurIcon);\n        }\n\n        internal void UpdateMultipleModeIconAndMenu()\n        {\n            Common.DoSomethingInUIThread(() =>\n            {\n                MenuAllPC.Checked = Common.NewDesMachineID == ID.ALL;\n                CurIcon = MenuAllPC.Checked ? Common.ICON_ALL : Common.ICON_ONE;\n                ChangeIcon(CurIcon);\n            });\n        }\n\n        // private bool checkClipboard = false;\n        protected override void WndProc(ref Message m)\n        {\n            const int WM_ENDSESSION = 0x0016;\n            const int WM_QUERYENDSESSION = 0x0011;\n\n            // const int WM_DRAWCLIPBOARD = 0x0308;\n            // const int WM_CHANGECBCHAIN = 0x030D;\n            switch (m.Msg)\n            {\n                /*\n                case WM_DRAWCLIPBOARD:\n                    if (Common.NextClipboardViewer != IntPtr.Zero && Common.NextClipboardViewer != this.Handle)\n                    {\n                        int rv = NativeMethods.SendMessage(Common.NextClipboardViewer, m.Msg, m.WParam, m.LParam);\n                        Common.Log(\"SendMessage returned \" + rv.ToString(CultureInfo.CurrentCulture));\n                    }\n\n                    if (Common.GetTick() - Common.LastClipboardEventTime < 1000)\n                    {\n                        Common.Log(\"GetTick() - lastClipboardEventTime < 1000\");\n                        Common.LastClipboardEventTime = Common.GetTick();\n                        return;\n                    }\n                    Common.LastClipboardEventTime = Common.GetTick();\n\n                    checkClipboard = true;//Do the task in a next message loop.\n                    break;\n\n                case WM_CHANGECBCHAIN:\n                    if (m.WParam == Common.NextClipboardViewer)\n                        Common.NextClipboardViewer = m.LParam;\n                    else\n                        if (Common.NextClipboardViewer != IntPtr.Zero && Common.NextClipboardViewer != this.Handle)\n                        {\n                            int rv = NativeMethods.SendMessage(Common.NextClipboardViewer, m.Msg, m.WParam, m.LParam);\n                            Common.Log(\"SendMessage returned \" + rv.ToString(CultureInfo.CurrentCulture));\n                        }\n                    break;\n                */\n\n                case NativeMethods.WM_SHOW_DRAG_DROP:\n                    Point p = default;\n                    _ = NativeMethods.GetCursorPos(ref p);\n                    Width = 70;\n                    Height = 70;\n                    Left = p.X - (Width / 3);\n                    Top = p.Y - (Height / 3);\n                    BackColor = Color.White;\n                    Opacity = 0.15;\n                    if (Cursor != dropCur)\n                    {\n                        Cursor = dropCur;\n                    }\n\n                    Show();\n                    break;\n\n                case NativeMethods.WM_HIDE_DRAG_DROP:\n                    Common.MainFormDot();\n\n                    /*\n                    this.Width = 1;\n                    this.Height = 1;\n                    this.Left = 0;\n                    this.Top = 0;\n                    //this.Hide();\n                    //Common.MainFormVisible = false;\n                     * */\n\n                    if (Cursor != dotCur)\n                    {\n                        Cursor = dotCur;\n                    }\n\n                    break;\n\n                case NativeMethods.WM_HIDE_DD_HELPER:\n                    Common.MainForm3Pixels();\n                    Common.MMSleep(0.2);\n                    if (m.WParam.ToInt32() == 1)\n                    {\n                        InputSimulation.MouseUp(); // A file is being dragged\n                    }\n\n                    IntPtr h = (IntPtr)NativeMethods.FindWindow(null, Common.HELPER_FORM_TEXT);\n\n                    if (h.ToInt32() > 0)\n                    {\n                        Logger.LogDebug(\"Hide Mouse Without Borders Helper.\");\n\n                        // Common.ShowWindow(h, 1);\n                        _ = NativeMethods.ShowWindow(h, 0);\n\n                        // Common.SetWindowPos(h, Common.HWND_NOTOPMOST, 10, 10, 50, 50, 0);\n                        // Common.SetWindowPos(h, Common.HWND_TOPMOST, 0, 0, 800, 60, 0);// For debug\n                    }\n\n                    break;\n\n                case NativeMethods.WM_CHECK_EXPLORER_DRAG_DROP:\n                    Logger.LogDebug(\"Got WM_CHECK_EXPLORER_DRAG_DROP!\");\n                    Common.DragDropStep04();\n                    break;\n\n                case NativeMethods.WM_QUIT:\n                    // Quit(true);\n                    break;\n\n                case NativeMethods.WM_SWITCH:\n                    break;\n\n                case WM_QUERYENDSESSION:\n                    Logger.LogDebug(\"WM_QUERYENDSESSION...\");\n                    Common.StartServiceAndSendLogoffSignal();\n                    break;\n\n                case WM_ENDSESSION:\n                    Quit(true, true);\n                    break;\n\n                case NativeMethods.WM_SHOW_SETTINGS_FORM:\n                    if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n                    {\n                        Common.ShowMachineMatrix();\n                    }\n\n                    break;\n\n                default:\n                    base.WndProc(ref m);\n                    break;\n            }\n        }\n\n        private void NotifyIcon_MouseDown(object sender, MouseEventArgs e)\n        {\n            if (e.Button == MouseButtons.Left)\n            {\n                Common.ShowMachineMatrix();\n            }\n        }\n\n        internal void SetTrayIconText(string value)\n        {\n            if (value.Length > 63)\n            {\n                value = value[..63];\n            }\n\n            NotifyIcon.Text = value;\n        }\n\n        internal void UpdateNotifyIcon()\n        {\n            string[] x = Common.MachineMatrix;\n            string iconText;\n            if (x != null && (x[0].Length > 0 || x[1].Length > 0 || x[2].Length > 0 || x[3].Length > 0))\n            {\n                iconText = Setting.Values.MatrixOneRow\n                    ? string.Format(\n                        CultureInfo.CurrentCulture,\n                        \"[{0}][{1}][{2}][{3}]\",\n                        x[0].Trim(),\n                        x[1].Trim(),\n                        x[2].Trim(),\n                        x[3].Trim())\n                    : string.Format(\n                        CultureInfo.CurrentCulture,\n                        \"[{0}][{1}]\\r\\n[{2}][{3}]\",\n                        x[0].Trim(),\n                        x[1].Trim(),\n                        x[2].Trim(),\n                        x[3].Trim());\n\n                SetTrayIconText(iconText);\n            }\n            else\n            {\n                SetTrayIconText(Application.ProductName);\n            }\n        }\n\n        internal void ShowToolTip(string txt, int timeOutInMilliseconds, ToolTipIcon icon = ToolTipIcon.Info, bool forceEvenIfHidingOldUI = false)\n        {\n            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n            {\n                var oldNotifyVisibility = NotifyIcon.Visible;\n\n                // In order to show tooltips, the icon needs to be shown.\n                if (forceEvenIfHidingOldUI)\n                {\n                    NotifyIcon.Visible = true;\n                }\n\n                NotifyIcon.ShowBalloonTip(timeOutInMilliseconds, Application.ProductName, txt, icon);\n                if (forceEvenIfHidingOldUI)\n                {\n                    NotifyIcon.Visible = oldNotifyVisibility;\n                }\n            }\n        }\n\n        private void MenuSendScreenCaptureClick(object sender, EventArgs e)\n        {\n            string menuCaption = (sender as ToolStripMenuItem).Text;\n            string captureFile = Common.CaptureScreen();\n\n            if (captureFile != null && File.Exists(captureFile))\n            {\n                if (menuCaption.Equals(\"此电脑\", StringComparison.OrdinalIgnoreCase))\n                {\n                    Common.OpenImage(captureFile);\n                }\n                else\n                {\n                    Common.SendImage(menuCaption, captureFile);\n                }\n            }\n        }\n\n        private void MenuGetScreenCaptureClick(object sender, EventArgs e)\n        {\n            string menuCaption = (sender as ToolStripMenuItem).Text;\n\n            // Send CaptureScreenCommand\n            ID des = menuCaption.Equals(\"所有电脑\", StringComparison.OrdinalIgnoreCase) ? ID.ALL : Common.IdFromName(menuCaption);\n            Common.SendPackage(des, PackageType.CaptureScreenCommand);\n        }\n\n        private void FrmScreen_Shown(object sender, EventArgs e)\n        {\n            Common.AssertOneInstancePerDesktopSession();\n\n            Common.MainForm = this;\n            Hide();\n            if (!Common.RunOnLogonDesktop && !Common.RunOnScrSaverDesktop)\n            {\n                NotifyIcon.Visible = false;\n                NotifyIcon.Visible = Setting.Values.ShowOriginalUI;\n            }\n\n            if (Program.ShowServiceModeErrorTooltip)\n            {\n                Common.ShowToolTip(\"服务启动失败，将以一般模式继续运行，请在设置中重新打开服务模式.\", 10000, forceEvenIfHidingOldUI: true);\n            }\n        }\n\n        private void MenuAbout_Click(object sender, EventArgs e)\n        {\n            if (Common.AboutForm == null)\n            {\n                _ = (Common.AboutForm = new FrmAbout()).ShowDialog();\n            }\n            else\n            {\n                Common.AboutForm.Activate();\n            }\n        }\n\n#if SHOW_ON_WINLOGON\n        private void ShowMouseWithoutBordersUiOnWinLogonDesktop(bool initMenuState)\n        {\n            Common.PaintCount = 0;\n            try\n            {\n                if (initMenuState)\n                {\n                    HideMenuWhenRunOnLogonDesktop();\n                }\n\n#if !USING_FORM\n                PaintMyNameOnDesktop();\n#else\n                if (fLogon == null) fLogon = new frmLogon();\n                fLogon.Show();\n                fLogon.LabelDesktop.ContextMenuStrip = fLogon.ContextMenuStrip = MainMenu;\n#endif\n            }\n            catch (Exception e)\n            {\n                Logger.Log(e);\n            }\n        }\n\n        internal void HideMenuWhenRunOnLogonDesktop()\n        {\n            menuHelp.Visible = false;\n            menuGetScreenCapture.Visible = false;\n            menuSendScreenCapture.Visible = false;\n            toolStripSeparator1.Visible = false;\n            toolStripSeparator2.Visible = false;\n            menuAbout.Visible = false;\n            menuMachineMatrix.Visible = false;\n            menuReinstallKeyboardAndMouseHook.Visible = false;\n            toolStripMenuItem1.Visible = false;\n            toolStripMenuItem2.Visible = false;\n            menuExit.Visible = false;\n        }\n#endif\n\n        private void MainMenu_MouseLeave(object sender, EventArgs e)\n        {\n#if SHOW_ON_WINLOGON\n            if (Common.RunOnLogonDesktop)\n            {\n                MainMenu.Hide();\n                Thread.Sleep(50);\n                PaintMyNameOnDesktop();\n            }\n#endif\n        }\n\n        private int colorB = 240;\n        private int colorBlueDelta = 5;\n        private bool turnedOff = true;\n\n        internal void ShowMessageOnLogonDesktop(bool turnOff)\n        {\n            if (turnOff && turnedOff)\n            {\n                colorB = 240;\n                colorBlueDelta = 5;\n                return;\n            }\n\n            turnedOff = false;\n            IntPtr hDesktop = NativeMethods.GetDesktopWindow();\n            IntPtr hdc = NativeMethods.GetWindowDC(hDesktop);\n            int textLengthInPixels;\n\n            if (hdc != IntPtr.Zero)\n            {\n                NativeMethods.RECT r;\n                string machineMatrix = Application.ProductName + \" is in multiple mode, keyboard may repeat in all machines: \";\n                r.Top = 0;\n                r.Left = Common.ScreenWidth / 5;\n                r.Right = Common.ScreenWidth - (Common.ScreenWidth / 5);\n                r.Bottom = 20;\n\n                for (int i = 0; i < Common.MAX_MACHINE; i++)\n                {\n                    string newMachine = Common.MachineMatrix[i].Trim();\n\n                    if (Common.MachinePool.TryFindMachineByName(newMachine, out MachineInf inf) && MachinePool.IsAlive(inf))\n                    {\n                        machineMatrix += \"[\" + inf.Name.Trim() + \"]\";\n                    }\n                }\n\n                if (turnOff)\n                {\n                    turnedOff = true;\n                    colorBlueDelta = -40;\n                    colorB = 0;\n                }\n                else\n                {\n                    colorBlueDelta = colorB == 255 ? -colorBlueDelta : colorB == 240 ? colorBlueDelta > 0 ? 5 : -40 : colorB == 0 ? -colorBlueDelta : colorBlueDelta;\n                    colorB += colorBlueDelta;\n                }\n\n                _ = NativeMethods.SetBkColor(hdc, 0);\n                _ = NativeMethods.SetTextColor(hdc, colorB << 8);\n                _ = NativeMethods.DrawText(hdc, machineMatrix, machineMatrix.Length, ref r, 0x1 | 0x4 | 0x100 | 0x400);\n                textLengthInPixels = r.Right - r.Left;\n                r.Left = (Common.ScreenWidth - textLengthInPixels) / 2;\n                r.Right = r.Left + textLengthInPixels;\n                _ = NativeMethods.DrawText(hdc, machineMatrix, machineMatrix.Length, ref r, 0x1 | 0x4 | 0x100);\n                _ = NativeMethods.ReleaseDC(hDesktop, hdc);\n            }\n        }\n\n#if SHOW_ON_WINLOGON\n        private const byte MIN_COLOR = 185;\n        private const byte MAX_COLOR = 255;\n        private const byte MIN_COLOR_DOWN = 10;\n        private byte paintColorR = MIN_COLOR;\n        private byte paintColorG = MIN_COLOR;\n        private byte paintColorB = MIN_COLOR;\n        private bool paintColorDown;\n\n        internal void PaintMyNameOnDesktop()\n        {\n            if (Setting.Values.HideLogonLogo)\n            {\n                return;\n            }\n\n            if (Common.PaintCount > 1500)\n            {\n                return; // running for 5 mins only\n            }\n\n            Common.PaintCount++;\n            IntPtr hDesktop = NativeMethods.GetDesktopWindow();\n            IntPtr hdc = NativeMethods.GetWindowDC(hDesktop);\n            if (hdc != IntPtr.Zero)\n            {\n                int c;\n\n                // int rv = NativeMethods.DrawText(hdc, Common.BinaryName, 10, ref r, 0);\n                for (int i = 0; i < logonLogo.GetUpperBound(0); i++)\n                {\n                    for (int j = 0; j < logonLogo.GetUpperBound(1); j++)\n                    {\n                        if (logonLogo[i, j] != -1)\n                        {\n                            c = logonLogo[i, j];\n                            if (c == 0xFFFFFF)\n                            {\n                                c = (paintColorB << 16) | (paintColorG << 8) | paintColorR;\n                            }\n\n                            int rv = (int)NativeMethods.SetPixel(hdc, i, j, (uint)c);\n                        }\n                    }\n                }\n\n                // Common.Log(\"PaintMyNameOnDesktop: last rv = \" + rv.ToString(CultureInfo.CurrentCulture));\n                _ = NativeMethods.ReleaseDC(hDesktop, hdc);\n            }\n\n            if (!paintColorDown)\n            {\n                if (paintColorR < MAX_COLOR)\n                {\n                    paintColorR += MIN_COLOR_DOWN;\n                }\n                else\n                {\n                    if (paintColorG < MAX_COLOR)\n                    {\n                        paintColorG += MIN_COLOR_DOWN;\n                    }\n                    else\n                    {\n                        if (paintColorB < MAX_COLOR)\n                        {\n                            paintColorB += MIN_COLOR_DOWN;\n                        }\n                        else\n                        {\n                            paintColorDown = true;\n                        }\n                    }\n                }\n            }\n            else\n            {\n                if (paintColorB > MIN_COLOR)\n                {\n                    paintColorB -= MIN_COLOR_DOWN;\n                }\n                else\n                {\n                    if (paintColorR > MIN_COLOR)\n                    {\n                        paintColorR -= MIN_COLOR_DOWN;\n                    }\n                    else\n                    {\n                        if (paintColorG > MIN_COLOR)\n                        {\n                            paintColorG -= MIN_COLOR_DOWN;\n                        }\n                        else\n                        {\n                            paintColorDown = false;\n                        }\n                    }\n                }\n            }\n        }\n#endif\n\n        private void MenuHelp_Click(object sender, EventArgs e)\n        {\n        }\n\n        internal void MenuReinstallKeyboardAndMouseHook_Click(object sender, EventArgs e)\n        {\n            Common.DoSomethingInTheInputCallbackThread(() =>\n            {\n                if (Common.Hook != null)\n                {\n                    Common.Hook.Stop();\n                    Common.Hook = null;\n                }\n\n                Common.InputCallbackForm.Close();\n                Common.InputCallbackForm = null;\n                Program.StartInputCallbackThread();\n            });\n        }\n\n        private void MenuGenDumpFile_Click(object sender, EventArgs e)\n        {\n            Logger.GenerateLog();\n        }\n\n        private void MainMenu_Opening(object sender, CancelEventArgs e)\n        {\n            UpdateMenu();\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/App/Helper/FormHelper.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.Specialized;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.Drawing.Imaging;\nusing System.Globalization;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Threading;\nusing System.Windows.Forms;\n\nnamespace MouseWithoutBorders\n{\n    public partial class FormHelper : System.Windows.Forms.Form\n    {\n        private readonly List<FocusArea> focusZone = new();\n        private readonly Lock bmScreenLock = new();\n        private long lastClipboardEventTime;\n\n        private IClipboardHelper remoteClipboardHelper;\n        private const string TEXT_TYPE_SEP = \"{4CFF57F7-BEDD-43d5-AE8F-27A61E886F2F}\";\n\n        private const int MAX_TEXT_SIZE = 20 * 1024 * 1024;\n        private const int MAX_IMAGE_SIZE = 50 * 1024 * 1024;\n\n        private struct FocusArea\n        {\n            internal RectangleF Rec;\n            internal Color Color;\n\n            internal FocusArea(RectangleF rec, Color color)\n            {\n                Rec = rec;\n                Color = color;\n            }\n        }\n\n        private Point focus1 = Point.Empty;\n        private Point focus2 = Point.Empty;\n\n        public FormHelper()\n        {\n            remoteClipboardHelper = IpcHelper.CreateIpcClient();\n\n            if (remoteClipboardHelper == null)\n            {\n                QuitDueToCommunicationError();\n                return;\n            }\n\n            SetDPIAwareness();\n            InitializeComponent();\n            lastClipboardEventTime = GetTick();\n            ClipboardMMHelper.HookClipboard(this);\n        }\n\n        private void SetDPIAwareness()\n        {\n            int setProcessDpiAwarenessResult = -1;\n\n            try\n            {\n                setProcessDpiAwarenessResult = NativeMethods.SetProcessDpiAwareness(2);\n                SendLog(string.Format(CultureInfo.InvariantCulture, \"SetProcessDpiAwareness: {0}.\", setProcessDpiAwarenessResult));\n            }\n            catch (DllNotFoundException)\n            {\n                SendLog(\"SetProcessDpiAwareness is unsupported in Windows 7 and lower.\");\n            }\n            catch (Exception e)\n            {\n                SendLog(e.ToString());\n            }\n\n            try\n            {\n                if (setProcessDpiAwarenessResult != 0)\n                {\n                    SendLog(string.Format(CultureInfo.InvariantCulture, \"SetProcessDPIAware: {0}.\", NativeMethods.SetProcessDPIAware()));\n                }\n            }\n            catch (Exception e)\n            {\n                SendLog(e.ToString());\n            }\n        }\n\n        private bool quitDueToCommunicationError;\n\n        private void QuitDueToCommunicationError()\n        {\n            if (!quitDueToCommunicationError)\n            {\n                quitDueToCommunicationError = true;\n\n                if (Process.GetCurrentProcess().SessionId != NativeMethods.WTSGetActiveConsoleSessionId())\n                {\n                    EventLogger.LogEvent(Application.ProductName + \" cannot be used in a remote desktop or virtual machine session.\");\n                }\n                else\n                {\n                    _ = MessageBox.Show(\n                        \"无法连接到无界鼠标进程，剪贴板共享功能失效.\\r\\n查看事件日志来获取更多信息.\",\n                        Text,\n                        MessageBoxButtons.OK,\n                        MessageBoxIcon.Error);\n                }\n\n                Process.GetCurrentProcess().Kill();\n            }\n        }\n\n        private void FormHelper_DragEnter(object sender, DragEventArgs e)\n        {\n            object o = e.Data.GetData(DataFormats.FileDrop);\n\n            if (o != null)\n            {\n                e.Effect = DragDropEffects.Copy;\n                Array ar = (string[])o;\n\n                if (ar.Length > 0)\n                {\n                    string fileName = ar.GetValue(0).ToString();\n                    Hide();\n\n                    try\n                    {\n                        remoteClipboardHelper.SendDragFile(fileName);\n                    }\n                    catch (Exception ex)\n                    {\n                        EventLogger.LogEvent(\"FormHelper_DragEnter: \" + ex.Message, EventLogEntryType.Error);\n                        QuitDueToCommunicationError();\n                    }\n                }\n            }\n        }\n\n        private void TimerHelper_Tick(object sender, EventArgs e)\n        {\n            lock (bmScreenLock)\n            {\n                if (picScr == null)\n                {\n                    timerHelper.Stop();\n                    Hide();\n                }\n            }\n        }\n\n        private void FormHelper_Shown(object sender, EventArgs e)\n        {\n            timerHelper.Start(); // To be sure.\n            Hide();\n        }\n\n        internal void SendLog(string log)\n        {\n            try\n            {\n                EventLogger.LogEvent(log, EventLogEntryType.Warning);\n            }\n            catch (Exception e)\n            {\n                EventLogger.LogEvent(log + \" ==> SendLog Exception: \" + e.Message, EventLogEntryType.Warning);\n            }\n        }\n\n        private long GetTick() // ms\n        {\n            return DateTime.Now.Ticks / 10000;\n        }\n\n        private string GetClipboardText()\n        {\n            string st = string.Empty, tmp = ClipboardMMHelper.GetText(TextDataFormat.UnicodeText);\n            int txtL = 0, rtfL = 0, htmL = 0;\n\n            if (tmp != null && (txtL = tmp.Length) > 0)\n            {\n                st += \"TXT\" + tmp + TEXT_TYPE_SEP;\n            }\n\n            tmp = ClipboardMMHelper.GetText(TextDataFormat.Rtf);\n\n            if (tmp != null && (rtfL = tmp.Length) > 0)\n            {\n                st += \"RTF\" + tmp + TEXT_TYPE_SEP;\n            }\n\n            tmp = ClipboardMMHelper.GetText(TextDataFormat.Html);\n\n            if (tmp != null && (htmL = tmp.Length) > 0)\n            {\n                st += \"HTM\" + tmp + TEXT_TYPE_SEP;\n            }\n\n            if (st.Length > 0)\n            {\n                if (st.Length > MAX_TEXT_SIZE)\n                {\n                    st = null;\n\n                    SendLog(string.Format(CultureInfo.CurrentCulture, \"GetClipboardText, Text too big: TXT = {0}, RTF = {1}, HTM = {2}.\", txtL, rtfL, htmL));\n                }\n                else\n                {\n                    SendLog(string.Format(CultureInfo.CurrentCulture, \"GetClipboardText: TXT = {0}, RTF = {1}, HTM = {2}.\", txtL, rtfL, htmL));\n                }\n            }\n\n            return st;\n        }\n\n#pragma warning disable CA2213 // Disposing is done by ComponentResourceManager\n        private Image bmScreen;\n        private Point startOrg;\n        private Point start;\n        private Point stop;\n        private PictureBox left;\n        private PictureBox top;\n        private PictureBox right;\n        private PictureBox bottom;\n        private PictureBox picScr;\n#pragma warning restore CA2213\n        private int customScreenCaptureInProgress;\n        private int screenLeft;\n        private int screenTop;\n\n        protected override void WndProc(ref Message m)\n        {\n            const int WM_DRAWCLIPBOARD = 0x0308;\n            const int WM_CHANGECBCHAIN = 0x030D;\n            const int WM_CLIPBOARDUPDATE = 0x031D;\n\n            switch (m.Msg)\n            {\n                case WM_DRAWCLIPBOARD:\n                case WM_CLIPBOARDUPDATE:\n                    ClipboardMMHelper.PassMessageToTheNextViewer(m);\n\n                    if (GetTick() - lastClipboardEventTime < 1000)\n                    {\n                        lastClipboardEventTime = GetTick();\n                        return;\n                    }\n\n                    if (customScreenCaptureInProgress > 0)\n                    {\n                        // 10 secs timeout for a failed capture.\n                        if (GetTick() - lastClipboardEventTime < 10000)\n                        {\n                            return;\n                        }\n                        else\n                        {\n                            customScreenCaptureInProgress = 0;\n                        }\n                    }\n\n                    lastClipboardEventTime = GetTick();\n\n                    ByteArrayOrString? data = null;\n                    bool isFile = false;\n\n                    if (ClipboardMMHelper.ContainsText())\n                    {\n                        data = GetClipboardText();\n                    }\n                    else if (ClipboardMMHelper.ContainsImage())\n                    {\n                        MemoryStream ms = new();\n                        Image im = ClipboardMMHelper.GetImage();\n\n                        if (im != null)\n                        {\n                            im.Save(ms, ImageFormat.Png);\n\n                            if (ms.Length > 0)\n                            {\n                                if (ms.Length > MAX_IMAGE_SIZE)\n                                {\n                                    SendLog(\"Image from clipboard, image too big: \" + ms.Length.ToString(CultureInfo.InvariantCulture));\n                                }\n                                else\n                                {\n                                    data = ms.GetBuffer();\n                                    SendLog(\"Image from clipboard: \" + ms.Length.ToString(CultureInfo.InvariantCulture));\n                                }\n                            }\n                            else\n                            {\n                                SendLog(\"ClipboardMMHelper image is 0 in length.\");\n                            }\n                        }\n                        else\n                        {\n                            SendLog(\"ClipboardMMHelper image (GetImage) is null.\");\n                        }\n\n                        ms.Dispose();\n                    }\n                    else if (ClipboardMMHelper.ContainsFileDropList())\n                    {\n                        StringCollection files = ClipboardMMHelper.GetFileDropList();\n\n                        if (files != null)\n                        {\n                            if (files.Count > 0)\n                            {\n                                data = files[0];\n                                isFile = true;\n\n                                SendLog(\"File from clipboard: \" + files[0]);\n                            }\n                            else\n                            {\n                                SendLog(\"GetFileDropList returned no file.\");\n                            }\n                        }\n                        else\n                        {\n                            SendLog(\"GetFileDropList returned null.\");\n                        }\n                    }\n                    else\n                    {\n                        SendLog(\"ClipboardMMHelper does not have text/image/file data.\");\n                        return;\n                    }\n\n                    if (data != null)\n                    {\n                        try\n                        {\n                            remoteClipboardHelper.SendClipboardData((ByteArrayOrString)data, isFile);\n                        }\n                        catch (Exception ex)\n                        {\n                            EventLogger.LogEvent(\"WM_DRAWCLIPBOARD: \" + ex.Message, EventLogEntryType.Error);\n                            QuitDueToCommunicationError();\n                        }\n\n                        GC.Collect();\n                    }\n                    else\n                    {\n                        SendLog(\"Null clipboard data returned. See previous messages (if any) for more information.\");\n                    }\n\n                    break;\n\n                case WM_CHANGECBCHAIN:\n                    if (!ClipboardMMHelper.UpdateNextClipboardViewer(m))\n                    {\n                        ClipboardMMHelper.PassMessageToTheNextViewer(m);\n                    }\n\n                    break;\n\n                case 0x401:\n                    screenLeft = 0;\n                    screenTop = 0;\n\n                    foreach (Screen s in Screen.AllScreens)\n                    {\n                        if (s.Bounds.Left < screenLeft)\n                        {\n                            screenLeft = s.Bounds.Left;\n                        }\n\n                        if (s.Bounds.Top < screenTop)\n                        {\n                            screenTop = s.Bounds.Top;\n                        }\n                    }\n\n                    customScreenCaptureInProgress = 1;\n                    lastClipboardEventTime = GetTick();\n                    SendLog(\"**************************************************\\r\\nScreen capture triggered.\");\n                    m.Result = new IntPtr(1);\n                    break;\n\n                case 0x406:\n                    if (m.Msg == 0x406)\n                    {\n                        lock (bmScreenLock)\n                        {\n                            bmScreen = null;\n\n                            for (int i = 0; i < 30; i++)\n                            {\n                                Thread.Sleep(100);\n\n                                if (ClipboardMMHelper.ContainsImage())\n                                {\n                                    bmScreen = ClipboardMMHelper.GetImage();\n                                    customScreenCaptureInProgress = 1;\n                                    break;\n                                }\n                            }\n\n                            if (bmScreen == null)\n                            {\n                                customScreenCaptureInProgress = 0;\n                                SendLog(\"No image found in the clipboard.\");\n                            }\n                            else\n                            {\n                                Opacity = 1;\n                                picScr = new PictureBox();\n                                picScr.Dock = DockStyle.Fill;\n                                picScr.SizeMode = PictureBoxSizeMode.StretchImage;\n                                picScr.Image = bmScreen;\n                                picScr.Refresh();\n                                Controls.Add(picScr);\n                                AssignEventHandlers(picScr);\n                            }\n                        }\n                    }\n\n                    MouseMoveHandler();\n                    break;\n\n                case 0x407:\n                    Program.DotForm.SetPosition(m.WParam.ToInt32(), m.LParam.ToInt32());\n                    Program.DotForm.TopMost = true;\n                    Program.DotForm.Show();\n                    Application.DoEvents();\n\n                    // Simulate input to help bring to the foreground, as it doesn't seem to work in every case otherwise.\n                    NativeMethods.INPUT input = new NativeMethods.INPUT { type = (int)NativeMethods.InputType.INPUT_MOUSE, mi = { } };\n                    NativeMethods.INPUT[] inputs = new NativeMethods.INPUT[] { input };\n                    _ = NativeMethods.SendInput(1, inputs, Marshal.SizeOf(typeof(NativeMethods.INPUT)));\n                    m.Result = SetForeGround() ? new IntPtr(1) : IntPtr.Zero;\n                    break;\n\n                case 0x408:\n                    Program.DotForm.Hide();\n                    break;\n\n                case 0x400:\n                    m.Result = Handle;\n                    break;\n\n                case SharedConst.QUIT_CMD:\n                    Process.GetCurrentProcess().Kill();\n                    break;\n\n                default:\n                    base.WndProc(ref m);\n                    break;\n            }\n        }\n\n        private bool SetForeGround()\n        {\n            string logTag = nameof(SetForeGround);\n            IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();\n\n            if (foreGroundWindow == Program.DotForm.Handle)\n            {\n                SendLog($\"{logTag}.Foreground window is already the dot form: {foreGroundWindow}.\");\n                return true;\n            }\n\n            Program.DotForm.Activate();\n\n            bool setForegroundWindow = NativeMethods.SetForegroundWindow(Program.DotForm.Handle);\n            SendLog($\"{logTag}.{nameof(NativeMethods.SetForegroundWindow)}({Program.DotForm.Handle}) returned: {setForegroundWindow}.\");\n\n            return LogForeGroundWindow(logTag);\n        }\n\n        private bool LogForeGroundWindow(string logTag)\n        {\n            IntPtr foreGroundWindow = NativeMethods.GetForegroundWindow();\n\n            if (foreGroundWindow == Program.DotForm.Handle)\n            {\n                SendLog($\"{logTag}.Foreground window is now the dot form: {Program.DotForm.Handle}.\");\n                return true;\n            }\n            else\n            {\n                SendLog($\"{logTag}.Foreground window is: [{foreGroundWindow}].\");\n                return false;\n            }\n        }\n\n        private void AssignEventHandlers(PictureBox p)\n        {\n            p.MouseDown += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseDown);\n            p.MouseMove += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseMove);\n            p.MouseUp += new System.Windows.Forms.MouseEventHandler(FormHelper_MouseUp);\n        }\n\n        private void MouseMoveHandler()\n        {\n            lock (bmScreenLock)\n            {\n                if (bmScreen != null && Opacity == 1)\n                {\n                    focusZone.Clear();\n                    TopMost = true;\n                    Show();\n\n                    startOrg = new Point(MousePosition.X - screenLeft, MousePosition.Y - screenTop);\n\n                    if (left == null)\n                    {\n                        left = new PictureBox();\n                        left.BackColor = Color.Red;\n                        Controls.Add(left);\n                        left.BringToFront();\n                        AssignEventHandlers(left);\n                    }\n\n                    left.Left = startOrg.X;\n                    left.Top = startOrg.Y;\n                    left.Width = 2;\n                    left.Height = 100;\n                    left.Show();\n                    left.Refresh();\n\n                    if (top == null)\n                    {\n                        top = new PictureBox();\n                        top.BackColor = Color.Red;\n                        Controls.Add(top);\n                        top.BringToFront();\n                        AssignEventHandlers(top);\n                    }\n\n                    top.Left = startOrg.X;\n                    top.Top = startOrg.Y;\n                    top.Height = 2;\n                    top.Width = 100;\n                    top.Show();\n                    top.Refresh();\n                }\n            }\n        }\n\n        private void MouseDownMoveHandler()\n        {\n            lock (bmScreenLock)\n            {\n                if (bmScreen != null && left != null && top != null)\n                {\n                    int x = MousePosition.X - screenLeft;\n                    int y = MousePosition.Y - screenTop;\n\n                    start = new Point(startOrg.X < x ? startOrg.X : x, startOrg.Y < y ? startOrg.Y : y);\n                    stop = new Point(startOrg.X > x ? startOrg.X : x, startOrg.Y > y ? startOrg.Y : y);\n\n                    left.Left = start.X;\n                    left.Top = start.Y;\n                    left.Width = 2;\n                    left.Height = stop.Y - start.Y;\n                    left.Show();\n\n                    top.Left = start.X;\n                    top.Top = start.Y;\n                    top.Height = 2;\n                    top.Width = stop.X - start.X;\n                    top.Show();\n\n                    if (right == null)\n                    {\n                        right = new PictureBox();\n                        right.BackColor = Color.Red;\n                        Controls.Add(right);\n                        right.BringToFront();\n                        AssignEventHandlers(right);\n                    }\n\n                    right.Left = stop.X;\n                    right.Top = start.Y;\n                    right.Width = 2;\n                    right.Height = stop.Y - start.Y;\n                    right.Show();\n\n                    if (bottom == null)\n                    {\n                        bottom = new PictureBox();\n                        bottom.BackColor = Color.Red;\n                        Controls.Add(bottom);\n                        bottom.BringToFront();\n                        AssignEventHandlers(bottom);\n                    }\n\n                    bottom.Left = start.X;\n                    bottom.Top = stop.Y;\n                    bottom.Height = 2;\n                    bottom.Width = stop.X - start.X;\n                    bottom.Show();\n\n                    TopMost = true;\n                    Show();\n                }\n            }\n        }\n\n        private void MouseUpHandler(bool canceled = false, bool rightMouseButton = false)\n        {\n            lock (bmScreenLock)\n            {\n                MouseDownMoveHandler();\n                customScreenCaptureInProgress = 0;\n\n                if (!canceled && bmScreen != null && left != null && top != null && right != null && bottom != null\n                    && stop.X - start.X > 0 && stop.Y - start.Y > 0)\n                {\n                    start = PointInStandardDPI(start);\n                    stop = PointInStandardDPI(stop);\n                    Bitmap bm = new(stop.X - start.X, stop.Y - start.Y);\n                    Graphics g = Graphics.FromImage(bm);\n\n                    try\n                    {\n                        g.DrawImage(bmScreen, 0, 0, new Rectangle(start, bm.Size), GraphicsUnit.Pixel);\n                        g.DrawRectangle(Pens.DarkOrange, 0, 0, stop.X - start.X - 1, stop.Y - start.Y - 1);\n\n                        foreach (FocusArea f in focusZone)\n                        {\n                            RectangleF rec = RectangleFInStandardDPI(f.Rec);\n                            rec.X -= start.X;\n                            rec.Y -= start.Y;\n\n                            g.DrawEllipse(new Pen(f.Color, 2), rec);\n                        }\n\n                        if (rightMouseButton)\n                        {\n                            try\n                            {\n                                string tempFile = Path.GetTempPath() + Path.GetFileNameWithoutExtension(Path.GetTempFileName()) + \".png\";\n                                SendLog(tempFile);\n                                bm.Save(tempFile, ImageFormat.Png);\n                                lastClipboardEventTime = GetTick();\n                                ClipboardMMHelper.SetText(tempFile);\n                            }\n                            catch (IOException ioException)\n                            {\n                                SendLog(\"IO!Exception!: \" + ioException.Message);\n                            }\n                            catch (ArgumentNullException argException)\n                            {\n                                SendLog(\"ArgNull!Exception!: \" + argException.Message);\n                            }\n                            catch (ExternalException internalException)\n                            {\n                                SendLog(\"Internal!Exception!: \" + internalException.Message);\n                            }\n                        }\n                        else\n                        {\n                            lastClipboardEventTime = GetTick() - 10000;\n                            ClipboardMMHelper.SetImage(bm);\n                        }\n                    }\n                    finally\n                    {\n                        g.Dispose();\n                        bm.Dispose();\n                        bmScreen.Dispose();\n                        bmScreen = null;\n                    }\n                }\n\n                ShowInTaskbar = false;\n                Hide();\n                Controls.Clear();\n                Opacity = 0.11;\n                left?.Dispose();\n                top?.Dispose();\n                right?.Dispose();\n                bottom?.Dispose();\n                picScr?.Dispose();\n                left = top = right = bottom = picScr = null;\n\n                SendLog(\"Screen capture ended.\\r\\n**************************************************\");\n            }\n        }\n\n        private void FormHelper_FormClosed(object sender, FormClosedEventArgs e)\n        {\n            ClipboardMMHelper.UnhookClipboard();\n        }\n\n        private void FormHelper_LocationChanged(object sender, EventArgs e)\n        {\n            lock (bmScreenLock)\n            {\n                if (picScr == null && !timerHelper.Enabled)\n                {\n                    Opacity = 0.11;\n                    timerHelper.Start();\n                }\n            }\n        }\n\n        private void FormHelper_KeyDown(object sender, KeyEventArgs e)\n        {\n            if (e.KeyCode == Keys.Escape)\n            {\n                MouseUpHandler(true);\n            }\n\n            if (focus1.IsEmpty)\n            {\n                focus1 = stop;\n            }\n        }\n\n        private void FormHelper_KeyUp(object sender, KeyEventArgs e)\n        {\n            focus2 = stop;\n\n            float x = Math.Min(focus1.X, focus2.X);\n            float y = Math.Min(focus1.Y, focus2.Y);\n            float w = Math.Abs(focus1.X - focus2.X);\n            float h = Math.Abs(focus1.Y - focus2.Y);\n            x -= 0.25F * w;\n            y -= 0.25F * h;\n            w *= 1.5F;\n            h *= 1.5F;\n\n            focusZone.Add(new FocusArea(new RectangleF(x, y, w, h), e.KeyCode == Keys.B ? Color.Blue : e.KeyCode == Keys.G ? Color.Green : Color.Red));\n\n            focus1 = focus2 = Point.Empty;\n        }\n\n        private void FormHelper_FormClosing(object sender, FormClosingEventArgs e)\n        {\n            if (e.CloseReason == CloseReason.UserClosing)\n            {\n                e.Cancel = true;\n            }\n        }\n\n        private void FormHelper_MouseDown(object sender, MouseEventArgs e)\n        {\n            SendLog(\"Screen capture Mouse down.\");\n            MouseMoveHandler();\n            customScreenCaptureInProgress = 2;\n        }\n\n        private void FormHelper_MouseMove(object sender, MouseEventArgs e)\n        {\n            if (customScreenCaptureInProgress == 1)\n            {\n                MouseMoveHandler();\n            }\n            else if (customScreenCaptureInProgress == 2)\n            {\n                MouseDownMoveHandler();\n            }\n        }\n\n        private void FormHelper_MouseUp(object sender, MouseEventArgs e)\n        {\n            MouseUpHandler(false, e.Button == MouseButtons.Right);\n        }\n\n        private Point PointInStandardDPI(Point p)\n        {\n            // Since the process is DPI awareness, just log and return.\n            // TODO: Test in Win8/7/XP.\n            SendLog(string.Format(CultureInfo.CurrentCulture, \"this.Width={0}, this.Height={1}, bmScreen.Width={2}, bmScreen.Height={3}, x={4}, y={5}\", Width, Height, bmScreen.Width, bmScreen.Height, p.X, p.Y));\n            return p;\n        }\n\n        private RectangleF RectangleFInStandardDPI(RectangleF r)\n        {\n            // Since the process is DPI awareness, just return.\n            return r;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/MouseWithoutBorders/ModuleInterface/dllmain.cpp",
    "content": "﻿#include \"pch.h\"\n#include <interface/powertoy_module_interface.h>\n#include <common/SettingsAPI/settings_objects.h>\n#include <common/interop/shared_constants.h>\n#include \"trace.h\"\n#include \"generateSecurityDescriptor.h\"\n\n#include <common/logger/logger.h>\n#include <common/SettingsAPI/settings_helpers.h>\n\n#include <common/utils/process_path.h>\n#include <common/utils/resources.h>\n#include <common/utils/winapi_error.h>\n#include <common/utils/processApi.h>\n#include <common/utils/elevation.h>\n\nHINSTANCE g_hInst_MouseWithoutBorders = 0;\n\nBOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)\n{\n    switch (ul_reason_for_call)\n    {\n    case DLL_PROCESS_ATTACH:\n        g_hInst_MouseWithoutBorders = hModule;\n        Trace::MouseWithoutBorders::RegisterProvider();\n        break;\n    case DLL_THREAD_ATTACH:\n    case DLL_THREAD_DETACH:\n        break;\n    case DLL_PROCESS_DETACH:\n        Trace::MouseWithoutBorders::UnregisterProvider();\n        break;\n    }\n    return TRUE;\n}\n\nbool GetUserSid(const wchar_t* username, PSID& sid)\n{\n    DWORD sidSize = 0;\n    DWORD domainNameSize = 0;\n    SID_NAME_USE sidNameUse;\n\n    LookupAccountName(nullptr, username, nullptr, &sidSize, nullptr, &domainNameSize, &sidNameUse);\n    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)\n    {\n        Logger::error(\"Failed to get buffer sizes\");\n        return false;\n    }\n\n    sid = LocalAlloc(LPTR, sidSize);\n    LPWSTR domainName = static_cast<LPWSTR>(LocalAlloc(LPTR, domainNameSize * sizeof(wchar_t)));\n\n    if (!LookupAccountNameW(nullptr, username, sid, &sidSize, domainName, &domainNameSize, &sidNameUse))\n    {\n        Logger::error(\"Failed to lookup account name\");\n        LocalFree(sid);\n        LocalFree(domainName);\n        return false;\n    }\n\n    LocalFree(domainName);\n    return true;\n}\n\nstd::wstring GetCurrentUserSid()\n{\n    wchar_t username[UNLEN + 1];\n    DWORD usernameSize = UNLEN + 1;\n\n    std::wstring result;\n    if (!GetUserNameW(username, &usernameSize))\n    {\n        Logger::error(\"Failed to get the current user name\");\n        return result;\n    }\n\n    PSID sid;\n    if (GetUserSid(username, sid))\n    {\n        LPWSTR sidString;\n        if (ConvertSidToStringSid(sid, &sidString))\n        {\n            result = sidString;\n            LocalFree(sidString);\n        }\n        LocalFree(sid);\n    }\n    else\n    {\n        Logger::error(L\"Failed to get SID for user \\\"\");\n    }\n\n    return result;\n}\n\nstd::wstring escapeDoubleQuotes(const std::wstring& input)\n{\n    std::wstring output;\n    output.reserve(input.size());\n\n    for (const wchar_t& ch : input)\n    {\n        if (ch == L'\"')\n        {\n            output += L'\\\\';\n        }\n        output += ch;\n    }\n\n    return output;\n}\n\nconst static wchar_t* MODULE_NAME = L\"MouseWithoutBorders\";\nconst static wchar_t* MODULE_DESC = L\"A module to move your mouse across computers.\";\nconst static wchar_t* SERVICE_NAME = L\"PowerToys.MWB.Service\";\nconst static std::wstring_view USE_SERVICE_PROPERTY_NAME = L\"UseService\";\n\nclass MouseWithoutBorders : public PowertoyModuleIface\n{\n    std::wstring app_name;\n    std::wstring app_key;\n\nprivate:\n    bool m_enabled = false;\n    bool run_in_service_mode = false;\n    PROCESS_INFORMATION p_info = {};\n\n    bool is_enabled_by_default() const override\n    {\n        return false;\n    }\n\n    bool is_process_running()\n    {\n        return WaitForSingleObject(p_info.hProcess, 0) == WAIT_TIMEOUT;\n    }\n\n    void launch_process()\n    {\n        Logger::trace(L\"Launching PowerToys MouseWithoutBorders process\");\n        const std::wstring application_path = L\"PowerToys.MouseWithoutBorders.exe\";\n        STARTUPINFO info = { sizeof(info) };\n        std::wstring full_command_path = application_path;\n        if (run_in_service_mode)\n        {\n            full_command_path += L\" \";\n            full_command_path += USE_SERVICE_PROPERTY_NAME;\n        }\n\n        if (!CreateProcessW(application_path.c_str(), full_command_path.data(), nullptr, nullptr, true, {}, nullptr, nullptr, &info, &p_info))\n        {\n            DWORD error = GetLastError();\n            std::wstring message = L\"PowerToys MouseWithoutBorders failed to start with error: \";\n            message += std::to_wstring(error);\n            Logger::error(message);\n        }\n\n        Trace::MouseWithoutBorders::Activate();\n    }\n\n    void unregister_service()\n    {\n        SC_HANDLE schSCManager = OpenSCManagerW(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);\n\n        SC_HANDLE hService = OpenServiceW(schSCManager, SERVICE_NAME, SERVICE_STOP | DELETE);\n        if (!hService)\n        {\n            Logger::error(\"Failed to open MWB service\");\n            return;\n        }\n\n        SERVICE_STATUS ss;\n        if (ControlService(hService, SERVICE_CONTROL_STOP, &ss))\n        {\n            Sleep(1000);\n            for (int i = 0; i < 5; ++i)\n            {\n                while (QueryServiceStatus(hService, &ss))\n                {\n                    if (ss.dwCurrentState == SERVICE_STOP_PENDING)\n                    {\n                        Sleep(1000);\n                    }\n                    else\n                    {\n                        goto outer;\n                    }\n                }\n            }\n        }\n\n    outer:\n        BOOL deleteResult = DeleteService(hService);\n        CloseServiceHandle(hService);\n\n        if (!deleteResult)\n        {\n            Logger::error(\"Failed to delete MWB service\");\n            return;\n        }\n\n        Trace::MouseWithoutBorders::ToggleServiceRegistration(false);\n    }\n\n    void\n    register_service()\n    {\n        SC_HANDLE schSCManager = OpenSCManagerW(nullptr, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ALL_ACCESS);\n        if (schSCManager == nullptr)\n        {\n            Logger::error(L\"Couldn't open sc manager\");\n            return;\n        }\n\n        const auto closeSCM = wil::scope_exit([&] {\n            CloseServiceHandle(schSCManager);\n        });\n\n        SC_HANDLE schService = OpenServiceW(schSCManager, SERVICE_NAME, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG);\n\n        const auto closeService = wil::scope_exit([&] {\n            CloseServiceHandle(schService);\n        });\n\n        const auto servicePath = get_module_folderpath(g_hInst_MouseWithoutBorders) + L\"/PowerToys.MouseWithoutBordersService.exe\";\n\n        // Check that the service doesn't exist already and is not disabled\n        DWORD bytesNeeded;\n        LPQUERY_SERVICE_CONFIGW pServiceConfig = nullptr;\n        if (!QueryServiceConfigW(schService, nullptr, 0, &bytesNeeded))\n        {\n            if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)\n            {\n                pServiceConfig = static_cast<LPQUERY_SERVICE_CONFIGW>(LocalAlloc(LMEM_FIXED, bytesNeeded));\n                if (!QueryServiceConfigW(schService, pServiceConfig, bytesNeeded, &bytesNeeded))\n                {\n                    LocalFree(pServiceConfig);\n                    pServiceConfig = nullptr;\n                    CloseServiceHandle(schService);\n                }\n            }\n        }\n\n        // Pass local app data of the current user to the service\n        wil::unique_cotaskmem_string cLocalAppPath;\n        winrt::check_hresult(SHGetKnownFolderPath(FOLDERID_LocalAppData, 0, nullptr, &cLocalAppPath));\n\n        std::wstring localAppPath{ cLocalAppPath.get() };\n        std::wstring binaryWithArgsPath = L\"\\\"\";\n        binaryWithArgsPath += servicePath;\n        binaryWithArgsPath += L\"\\\" \";\n        binaryWithArgsPath += escapeDoubleQuotes(localAppPath);\n\n        bool alreadyRegistered = false;\n        bool isServicePathCorrect = true;\n        if (pServiceConfig)\n        {\n            std::wstring_view existingServicePath{ pServiceConfig->lpBinaryPathName };\n            alreadyRegistered = true;\n            isServicePathCorrect = (existingServicePath == binaryWithArgsPath);\n            if (isServicePathCorrect)\n            {\n                Logger::warn(L\"The service path is not correct. Current: {} Expected: {}\", existingServicePath, binaryWithArgsPath);\n            }\n\n            if (alreadyRegistered && pServiceConfig->dwStartType == SERVICE_DISABLED)\n            {\n                if (!ChangeServiceConfigW(schService,\n                                          SERVICE_NO_CHANGE,\n                                          SERVICE_DEMAND_START,\n                                          SERVICE_NO_CHANGE,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr))\n                {\n                    const bool markedForDelete = GetLastError() == ERROR_SERVICE_MARKED_FOR_DELETE;\n                    // We cannot remove the mark for deletion from the service.\n                    if (markedForDelete)\n                    {\n                        alreadyRegistered = false;\n                        CloseServiceHandle(schService);\n                    }\n                }\n            }\n            LocalFree(pServiceConfig);\n        }\n\n        if (alreadyRegistered)\n        {\n            if (!isServicePathCorrect)\n            {\n                if (!ChangeServiceConfigW(schService,\n                                          SERVICE_NO_CHANGE,\n                                          SERVICE_NO_CHANGE,\n                                          SERVICE_NO_CHANGE,\n                                          binaryWithArgsPath.c_str(),\n                                          nullptr,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr,\n                                          nullptr))\n                {\n                    Logger::error(L\"Failed to update the service's path. ERROR: {}\", GetLastError());\n                }\n                else\n                {\n                    Logger::info(L\"Updated the service's path.\");\n                }\n            }\n            return;\n        }\n\n        schService = CreateServiceW(\n            schSCManager,\n            SERVICE_NAME,\n            SERVICE_NAME,\n            SERVICE_ALL_ACCESS,\n            SERVICE_WIN32_OWN_PROCESS,\n            SERVICE_DEMAND_START,\n            SERVICE_ERROR_NORMAL,\n            binaryWithArgsPath.c_str(),\n            nullptr,\n            nullptr,\n            nullptr,\n            nullptr,\n            nullptr);\n\n        if (schService == nullptr)\n        {\n            Logger::error(L\"Failed to create service\");\n            return;\n        }\n\n        // Set up the security descriptor to allow non-elevated users to start the service\n        PSECURITY_DESCRIPTOR pSD = nullptr;\n        ULONG szSD = 0;\n        std::wstring securityDescriptor = generateSecurityDescriptor(GetCurrentUserSid());\n\n        if (!ConvertStringSecurityDescriptorToSecurityDescriptorW(\n                securityDescriptor.c_str(),\n                SDDL_REVISION_1,\n                &pSD,\n                &szSD))\n        {\n            Logger::error(L\"Failed to convert security descriptor string\");\n            CloseServiceHandle(schService);\n            return;\n        }\n\n        if (!SetServiceObjectSecurity(schService, DACL_SECURITY_INFORMATION, pSD))\n        {\n            Logger::error(\"Failed to set service object security\");\n        }\n\n        LocalFree(pSD);\n        CloseServiceHandle(schService);\n    }\n\n    void update_state_from_settings(const PowerToysSettings::PowerToyValues& values)\n    {\n        const bool new_run_in_service_mode = values.get_bool_value(USE_SERVICE_PROPERTY_NAME).value_or(false);\n\n        if (new_run_in_service_mode != run_in_service_mode)\n        {\n            run_in_service_mode = new_run_in_service_mode;\n\n            shutdown_processes();\n\n            if (new_run_in_service_mode)\n            {\n                register_service();\n            }\n            // Wait until Settings -> MWB IPC Shutdown() call is completed\n            else\n            {\n                const auto ps = getProcessHandlesByName(L\"PowerToys.MouseWithoutBorders.exe\", PROCESS_QUERY_LIMITED_INFORMATION);\n                for (const auto& p : ps)\n                {\n                    DWORD status = STILL_ACTIVE;\n                    do\n                    {\n                        GetExitCodeProcess(p.get(), &status);\n                    } while (status == STILL_ACTIVE);\n                }\n\n                Sleep(1000);\n            }\n\n            if (m_enabled)\n            {\n                launch_process();\n            }\n\n            Trace::MouseWithoutBorders::ToggleServiceRegistration(new_run_in_service_mode);\n        }\n    }\n\npublic:\n    MouseWithoutBorders()\n    {\n        app_name = L\"MouseWithoutBorders\";\n        app_key = app_name;\n        std::filesystem::path logFilePath(PTSettingsHelper::get_module_save_folder_location(app_key));\n        logFilePath.append(LogSettings::mouseWithoutBordersLogPath);\n        Logger::init(LogSettings::mouseWithoutBordersLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());\n\n        try\n        {\n            PowerToysSettings::PowerToyValues values =\n                PowerToysSettings::PowerToyValues::load_from_settings_file(MODULE_NAME);\n            update_state_from_settings(values);\n        }\n        catch (std::exception&)\n        {\n            // Initial start/\n        }\n    };\n\n    // Return the configured status for the gpo policy for the module\n    virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override\n    {\n        return powertoys_gpo::getConfiguredMouseWithoutBordersEnabledValue();\n    }\n\n    void shutdown_process(HANDLE handle)\n    {\n        auto cb = [](HWND hwnd, LPARAM lParam) -> BOOL {\n            DWORD processId;\n            GetWindowThreadProcessId(hwnd, &processId);\n\n            if (processId == lParam)\n            {\n                PostMessageW(hwnd, WM_CLOSE, 0, 0);\n                return FALSE;\n            }\n\n            return TRUE;\n        };\n\n        DWORD processId = GetProcessId(handle);\n        EnumWindows(cb, processId);\n\n        DWORD waitResult = WaitForSingleObject(handle, 3000);\n        if (waitResult != WAIT_OBJECT_0)\n        {\n            TerminateProcess(handle, 0);\n        }\n    }\n\n    void shutdown_processes()\n    {\n        const auto services = getProcessHandlesByName(L\"PowerToys.MouseWithoutBordersService.exe\", PROCESS_TERMINATE);\n        for (const auto& svc : services)\n            TerminateProcess(svc.get(), 0);\n        wil::unique_process_handle s;\n\n        std::array<std::wstring_view, 2> processes_names = { L\"PowerToys.MouseWithoutBorders.exe\",\n                                                             L\"PowerToys.MouseWithoutBordersHelper.exe\" };\n\n        for (const auto process : processes_names)\n        {\n            const auto apps = getProcessHandlesByName(process, PROCESS_TERMINATE);\n            for (const auto& app : apps)\n                shutdown_process(app.get());\n        }\n    }\n\n    virtual void destroy() override\n    {\n        shutdown_processes();\n        TerminateProcess(p_info.hProcess, 1);\n        delete this;\n    }\n\n    virtual const wchar_t* get_name() override\n    {\n        return MODULE_NAME;\n    }\n\n    virtual bool get_config(wchar_t* buffer, int* buffer_size) override\n    {\n        HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);\n\n        PowerToysSettings::Settings settings(hinstance, get_name());\n        settings.set_description(MODULE_DESC);\n\n        return settings.serialize_to_buffer(buffer, buffer_size);\n    }\n\n    virtual const wchar_t* get_key() override\n    {\n        return app_key.c_str();\n    }\n\n    virtual void set_config(const wchar_t* config) override\n    {\n        try\n        {\n            // Parse the input JSON string.\n            PowerToysSettings::PowerToyValues values =\n                PowerToysSettings::PowerToyValues::from_json_string(config, get_key());\n\n            update_state_from_settings(values);\n            // If you don't need to do any custom processing of the settings, proceed\n            // to persists the values.\n            values.save_to_settings_file();\n        }\n        catch (std::exception&)\n        {\n            // Improper JSON.\n        }\n    }\n\n    virtual void enable()\n    {\n        Trace::MouseWithoutBorders::Enable(true);\n\n        launch_process();\n\n        m_enabled = true;\n    };\n\n    virtual void disable()\n    {\n        if (m_enabled)\n        {\n            Trace::MouseWithoutBorders::Enable(false);\n            Logger::trace(L\"Disabling MouseWithoutBorders...\");\n\n            Logger::trace(L\"Signaled exit event for PowerToys MouseWithoutBorders.\");\n            TerminateProcess(p_info.hProcess, 1);\n\n            shutdown_processes();\n\n            CloseHandle(p_info.hProcess);\n        }\n\n        m_enabled = false;\n    }\n\n    virtual bool is_enabled() override\n    {\n        return m_enabled;\n    }\n\n    void launch_add_firewall_process()\n    {\n        Logger::trace(L\"Starting Process to add firewall rule\");\n\n        std::wstring executable_path = get_module_folderpath();\n        executable_path.append(L\"\\\\PowerToys.MouseWithoutBorders.exe\");\n\n        std::wstring executable_args = L\"\";\n        executable_args.append(L\"/S /c \\\"\");\n        executable_args.append(L\"chcp 65001>nul\");\n        executable_args.append(L\" & echo 为 PowerToys.MouseWithoutBorders.exe 删除所有原有的入站规则\");\n        executable_args.append(L\" & netsh advfirewall firewall delete rule dir=in name=all program=\\\"\");\n        executable_args.append(executable_path);\n        executable_args.append(L\"\\\" & echo 为 PowerToys.MouseWithoutBorders.exe 添加一条允许通过的入站规则\");\n        executable_args.append(L\" & netsh advfirewall firewall add rule name=\\\"PowerToys.MouseWithoutBorders\\\" dir=in action=allow program=\\\"\");\n        executable_args.append(executable_path);\n        executable_args.append(L\"\\\" enable=yes remoteip=LocalSubnet profile=any protocol=tcp & echo 现在可以关掉这个窗口了 & pause\\\"\");\n\n        SHELLEXECUTEINFOW sei{ sizeof(sei) };\n        sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };\n        sei.lpFile = L\"cmd.exe\";\n        sei.nShow = SW_SHOWNORMAL;\n        sei.lpParameters = executable_args.data();\n        sei.lpVerb = L\"runas\";\n\n        if (ShellExecuteExW(&sei))\n        {\n            Logger::trace(\"Successfully started the firewall rule adding process\");\n        }\n        else\n        {\n            Logger::error(L\"The firewall rule adding process failed to start. {}\", get_last_error_or_default(GetLastError()));\n        }\n    }\n\n    virtual void call_custom_action(const wchar_t* action) override\n    {\n        try\n        {\n            PowerToysSettings::CustomActionObject action_object =\n                PowerToysSettings::CustomActionObject::from_json_string(action);\n\n            if (action_object.get_name() == L\"add_firewall\")\n            {\n                launch_add_firewall_process();\n                Trace::MouseWithoutBorders::AddFirewallRule();\n            }\n            else if (action_object.get_name() == L\"uninstall_service\")\n            {\n                unregister_service();\n            }\n        }\n        catch (std::exception&)\n        {\n            Logger::error(L\"Failed to parse action. {}\", action);\n        }\n    }\n};\n\nextern \"C\" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()\n{\n    return new MouseWithoutBorders();\n}"
  },
  {
    "path": "PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <Import Project=\"..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.props\" Condition=\"Exists('..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.props')\" />\n  <Target Name=\"GenerateResourceFiles\" BeforeTargets=\"PrepareForBuild\">\n    <Exec Command=\"powershell -NonInteractive -executionpolicy Unrestricted $(SolutionDir)tools\\build\\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h new.base.rc new.rc\" />\n  </Target>\n  <PropertyGroup Label=\"Globals\">\n    <VCProjectVersion>17.0</VCProjectVersion>\n    <Keyword>Win32Proj</Keyword>\n    <ProjectGuid>{8acb33d9-c95b-47d4-8363-9731ee0930a0}</ProjectGuid>\n    <RootNamespace>NewPlusShellExtension</RootNamespace>\n    <WindowsTargetPlatformVersion>10.0.20348.0</WindowsTargetPlatformVersion>\n    <ProjectName>NewPlus.ShellExtension</ProjectName>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>true</UseDebugLibraries>\n    <PlatformToolset>v143</PlatformToolset>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <UseDebugLibraries>false</UseDebugLibraries>\n    <PlatformToolset>v143</PlatformToolset>\n    <WholeProgramOptimization>true</WholeProgramOptimization>\n    <CharacterSet>Unicode</CharacterSet>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Label=\"Shared\">\n  </ImportGroup>\n  <ImportGroup Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup Condition=\"'$(Configuration)'=='Debug'\">\n    <TargetExt>.dll</TargetExt>\n    <OutDir>..\\..\\..\\..\\$(Platform)\\$(Configuration)\\WinUI3Apps\\</OutDir>\n    <TargetName>PowerToys.NewPlus.ShellExtension</TargetName>\n    <IntDir>$(SolutionDir)$(Platform)\\$(Configuration)\\TemporaryBuild\\obj\\$(ProjectName)\\</IntDir>\n    <LinkIncremental />\n    <IgnoreImportLibrary />\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)'=='Release'\">\n    <OutDir>..\\..\\..\\..\\$(Platform)\\$(Configuration)\\WinUI3Apps\\</OutDir>\n    <TargetName>PowerToys.NewPlus.ShellExtension</TargetName>\n    <IntDir>$(SolutionDir)$(Platform)\\$(Configuration)\\TemporaryBuild\\obj\\$(ProjectName)\\</IntDir>\n    <LinkIncremental />\n    <IgnoreImportLibrary />\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Debug'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;_DEBUG;NEWPLUSCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <AdditionalIncludeDirectories>..\\..\\..\\common\\Telemetry;..\\..\\;..\\..\\..\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableUAC>false</EnableUAC>\n      <ModuleDefinitionFile>dll.def</ModuleDefinitionFile>\n      <AdditionalDependencies>runtimeobject.lib;$(CoreLibraryDependencies)</AdditionalDependencies>\n      <IgnoreSpecificDefaultLibraries>\n      </IgnoreSpecificDefaultLibraries>\n    </Link>\n    <PreBuildEvent>\n      <Command>del $(OutDir)\\NewPlusPackage.msix /q\nMakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv</Command>\n    </PreBuildEvent>\n    <PostBuildEvent>\n      <Command>\n      </Command>\n    </PostBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)'=='Release'\">\n    <ClCompile>\n      <WarningLevel>Level3</WarningLevel>\n      <FunctionLevelLinking>true</FunctionLevelLinking>\n      <IntrinsicFunctions>true</IntrinsicFunctions>\n      <SDLCheck>true</SDLCheck>\n      <PreprocessorDefinitions>WIN32;NDEBUG;NEWPLUSCONTEXTMENU_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <ConformanceMode>true</ConformanceMode>\n      <PrecompiledHeader>Use</PrecompiledHeader>\n      <PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>\n      <LanguageStandard>stdcpplatest</LanguageStandard>\n      <AdditionalIncludeDirectories>..\\..\\..\\common\\Telemetry;..\\..\\;..\\..\\..\\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n    </ClCompile>\n    <Link>\n      <SubSystem>Windows</SubSystem>\n      <EnableCOMDATFolding>true</EnableCOMDATFolding>\n      <OptimizeReferences>true</OptimizeReferences>\n      <GenerateDebugInformation>true</GenerateDebugInformation>\n      <EnableUAC>false</EnableUAC>\n      <ModuleDefinitionFile>dll.def</ModuleDefinitionFile>\n      <AdditionalDependencies>runtimeobject.lib;$(CoreLibraryDependencies)</AdditionalDependencies>\n      <IgnoreSpecificDefaultLibraries>\n      </IgnoreSpecificDefaultLibraries>\n    </Link>\n    <PreBuildEvent>\n      <Command>del $(OutDir)\\NewPlusPackage.msix /q\nMakeAppx.exe pack /d . /p $(OutDir)NewPlusPackage.msix /nv</Command>\n    </PreBuildEvent>\n    <PostBuildEvent>\n      <Command>\n      </Command>\n    </PostBuildEvent>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClInclude Include=\"dll_main.h\" />\n    <ClInclude Include=\"shell_context_menu.h\" />\n    <ClInclude Include=\"shell_context_sub_menu.h\" />\n    <ClInclude Include=\"shell_context_sub_menu_item.h\" />\n    <ClInclude Include=\"constants.h\" />\n    <ClInclude Include=\"settings.h\" />\n    <ClInclude Include=\"trace.h\" />\n    <ClInclude Include=\"new_utilities.h\" />\n    <ClInclude Include=\"resource.base.h\" />\n    <ClInclude Include=\"template_folder.h\" />\n    <ClInclude Include=\"pch.h\" />\n    <ClInclude Include=\"Generated Files/resource.h\" />\n    <ClInclude Include=\"template_item.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClCompile Include=\"new_utilities.cpp\" />\n    <ClCompile Include=\"shell_context_menu.cpp\" />\n    <ClCompile Include=\"shell_context_sub_menu.cpp\" />\n    <ClCompile Include=\"shell_context_sub_menu_item.cpp\" />\n    <ClCompile Include=\"dll_main.cpp\" />\n    <ClCompile Include=\"powertoys_module.cpp\" />\n    <ClCompile Include=\"settings.cpp\" />\n    <ClCompile Include=\"trace.cpp\" />\n    <ClCompile Include=\"template_folder.cpp\" />\n    <ClCompile Include=\"pch.cpp\">\n      <PrecompiledHeader>Create</PrecompiledHeader>\n    </ClCompile>\n    <ClCompile Include=\"template_item.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"dll.def\" />\n    <None Include=\"packages.config\" />\n    <CopyFileToFolders Include=\"TemplateExamples\\模板文件夹里的一切都会出现在新建+菜单中.txt\">\n      <DeploymentContent>true</DeploymentContent>\n      <FileType>Document</FileType>\n      <DestinationFolders>$(OutDir)\\Assets\\NewPlus\\Templates</DestinationFolders>\n    </CopyFileToFolders>\n    <CopyFileToFolders Include=\"TemplateExamples\\示例文件夹\\示例文本文件.txt\">\n      <DeploymentContent>true</DeploymentContent>\n      <FileType>Document</FileType>\n      <DestinationFolders>$(OutDir)\\Assets\\NewPlus\\Templates\\示例文件夹</DestinationFolders>\n    </CopyFileToFolders>\n    <CopyFileToFolders Include=\"TemplateExamples\\示例文件夹\\另一个示例文本文件.txt\">\n      <DeploymentContent>true</DeploymentContent>\n      <FileType>Document</FileType>\n      <DestinationFolders>$(OutDir)\\Assets\\NewPlus\\Templates\\示例文件夹</DestinationFolders>\n    </CopyFileToFolders>\n  </ItemGroup>\n  <ItemGroup>\n    <ProjectReference Include=\"..\\..\\..\\common\\logger\\logger.vcxproj\">\n      <Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\..\\common\\SettingsAPI\\SettingsAPI.vcxproj\">\n      <Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\..\\common\\Telemetry\\EtwTrace\\EtwTrace.vcxproj\">\n      <Project>{8f021b46-362b-485c-bfba-ccf83e820cbd}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\..\\common\\Themes\\Themes.vcxproj\">\n      <Project>{98537082-0fdb-40de-abd8-0dc5a4269bab}</Project>\n    </ProjectReference>\n    <ProjectReference Include=\"..\\..\\..\\common\\version\\version.vcxproj\">\n      <Project>{cc6e41ac-8174-4e8a-8d22-85dd7f4851df}</Project>\n    </ProjectReference>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Generated Files/new.rc\" />\n    <None Include=\"new.base.rc\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"Assets\\NewPlus\\LargeTile.png\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\New_dark.ico\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\New_light.ico\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Open_templates_dark.ico\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Open_templates_light.ico\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\SmallTile.png\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\SplashScreen.png\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square150x150Logo.png\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square44x44Logo.png\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\StoreLogo.png\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Wide310x150Logo.png\">\n      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"resources.resx\">\n      <SubType>Designer</SubType>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"AppxManifest.xml\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <Import Project=\"..\\..\\..\\..\\deps\\spdlog.props\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n    <Import Project=\"..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.targets\" Condition=\"Exists('..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" />\n  </ImportGroup>\n  <Target Name=\"EnsureNuGetPackageBuildImports\" BeforeTargets=\"PrepareForBuild\">\n    <PropertyGroup>\n      <ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them.  For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>\n    </PropertyGroup>\n    <Error Condition=\"!Exists('..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.props')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.props'))\" />\n    <Error Condition=\"!Exists('..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.targets')\" Text=\"$([System.String]::Format('$(ErrorText)', '..\\..\\..\\..\\packages\\Microsoft.Windows.CppWinRT.2.0.240111.5\\build\\native\\Microsoft.Windows.CppWinRT.targets'))\" />\n  </Target>\n</Project>"
  },
  {
    "path": "PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/NewShellExtensionContextMenu.vcxproj.filters",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup>\n    <ClCompile Include=\"shell_context_menu.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"shell_context_sub_menu.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"shell_context_sub_menu_item.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"template_folder.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"template_item.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"dll_main.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"pch.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"powertoys_module.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"settings.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"trace.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n    <ClCompile Include=\"new_utilities.cpp\">\n      <Filter>Source Files</Filter>\n    </ClCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"template_folder.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"template_item.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"shell_context_sub_menu_item.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"shell_context_sub_menu.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"shell_context_menu.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"pch.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"dll_main.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"constants.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"settings.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"trace.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"new_utilities.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"Generated Files/resource.h\">\n      <Filter>Generated Files</Filter>\n    </ClInclude>\n    <ClInclude Include=\"resource.base.h\">\n      <Filter>Header Files</Filter>\n    </ClInclude>\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"packages.config\" />\n    <None Include=\"Assets\\NewPlus\\SmallTile.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\SplashScreen.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square150x150Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square44x44Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\StoreLogo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Wide310x150Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\SmallTile.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\SplashScreen.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square150x150Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square44x44Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\StoreLogo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Wide310x150Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"resources.resx\">\n      <Filter>Resource Files</Filter>\n    </None>\n    <None Include=\"new.base.rc\">\n      <Filter>Resource Files</Filter>\n    </None>\n    <None Include=\"dll.def\">\n      <Filter>Source Files</Filter>\n    </None>\n    <None Include=\"AppxManifest.xml\">\n      <Filter>Source Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\SmallTile.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\SplashScreen.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square150x150Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Square44x44Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\StoreLogo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Wide310x150Logo.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\LargeTile.png\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\New_dark.ico\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\New_light.ico\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Open_templates_dark.ico\">\n      <Filter>Asset Files</Filter>\n    </None>\n    <None Include=\"Assets\\NewPlus\\Open_templates_light.ico\">\n      <Filter>Asset Files</Filter>\n    </None>\n  </ItemGroup>\n  <ItemGroup>\n    <Filter Include=\"Source Files\">\n      <UniqueIdentifier>{82bf7d46-1201-4fc2-99e0-6c1f48f97f1f}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Header Files\">\n      <UniqueIdentifier>{0c915b9c-0e6a-4d16-8620-507a10fc29c9}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Asset Files\">\n      <UniqueIdentifier>{0c64a1a0-1f9e-4663-8649-454da469d15c}</UniqueIdentifier>\n      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\n    </Filter>\n    <Filter Include=\"Resource Files\">\n      <UniqueIdentifier>{4f319851-7d86-4180-b3a3-fd497a320c34}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Generated Files\">\n      <UniqueIdentifier>{a998f674-d126-488b-8457-7673fe986f94}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Template Examples\">\n      <UniqueIdentifier>{b442cb0f-9f62-46e8-b269-fefa8ceacb21}</UniqueIdentifier>\n    </Filter>\n    <Filter Include=\"Template Examples\\示例文件夹\">\n      <UniqueIdentifier>{e7904759-7b6c-4609-9c6d-e3eae3cb866c}</UniqueIdentifier>\n    </Filter>\n  </ItemGroup>\n  <ItemGroup>\n    <ResourceCompile Include=\"Generated Files/new.rc\">\n      <Filter>Generated Files</Filter>\n    </ResourceCompile>\n  </ItemGroup>\n  <ItemGroup>\n    <CopyFileToFolders Include=\"TemplateExamples\\模板文件夹里的一切都会出现在新建+菜单中.txt\" />\n    <CopyFileToFolders Include=\"TemplateExamples\\示例文件夹\\示例文本文件.txt\" />\n    <CopyFileToFolders Include=\"TemplateExamples\\示例文件夹\\另一个示例文本文件.txt\" />\n  </ItemGroup>\n</Project>"
  },
  {
    "path": "PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/TemplateExamples/模板文件夹里的一切都会出现在新建+菜单中.txt",
    "content": "访问 https://aka.ms/PowerToysOverview_NewPlus 了解如何使用新建+"
  },
  {
    "path": "PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/TemplateExamples/示例文件夹/另一个示例文本文件.txt",
    "content": "另一个示例文本文件"
  },
  {
    "path": "PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/TemplateExamples/示例文件夹/示例文本文件.txt",
    "content": "示例文本文件"
  },
  {
    "path": "PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu/resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"context_menu_item_new\" xml:space=\"preserve\">\n    <value>新建+</value>\n    <comment>The main context menu item that users click on. This should be localized to match New in Windows. e.g. Danish it would become Ny+</comment>\n  </data>\n  <data name=\"context_menu_item_open_templates\" xml:space=\"preserve\">\n    <value>打开模板文件夹</value>\n    <comment>The menu item in the context menu that enables user to open the folder that contains their templates.</comment>\n  </data>\n  <data name=\"default_template_sub_folder_name_where_templates_are_stored\" xml:space=\"preserve\">\n    <value>模板</value>\n    <comment>Default subfolder name where templates are stored.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/NewPlus/NewShellExtensionContextMenu.win10/resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"context_menu_item_new\" xml:space=\"preserve\">\n    <value>新建+</value>\n    <comment>The main context menu item that users click on. This should be localized to match New in Windows. e.g. Danish it would become Ny+</comment>\n  </data>\n  <data name=\"context_menu_item_open_templates\" xml:space=\"preserve\">\n    <value>打开模板文件夹</value>\n    <comment>The menu item in the context menu that enables user to open the folder that contains their templates.</comment>\n  </data>\n  <data name=\"default_template_sub_folder_name_where_templates_are_stored\" xml:space=\"preserve\">\n    <value>模板</value>\n    <comment>Default subfolder name where templates are stored.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/PowerOCR/PowerOCR/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Cancel\" xml:space=\"preserve\">\n    <value>关闭</value>\n  </data>\n  <data name=\"CancelShortcut\" xml:space=\"preserve\">\n    <value>关闭 (Esc)</value>\n    <comment>(Esc) indicates the keyboard shortcut</comment>\n  </data>\n  <data name=\"ResultTextSingleLine\" xml:space=\"preserve\">\n    <value>单行</value>\n  </data>\n  <data name=\"ResultTextSingleLineShortcut\" xml:space=\"preserve\">\n    <value>单行 (S)</value>\n    <comment>(S) indicates the keyboard shortcut</comment>\n  </data>\n  <data name=\"ResultTextTable\" xml:space=\"preserve\">\n    <value>表格</value>\n  </data>\n  <data name=\"ResultTextTableShortcut\" xml:space=\"preserve\">\n    <value>表格 (T)</value>\n    <comment>(T) indicates the keyboard shortcut</comment>\n  </data>\n  <data name=\"SelectedLang\" xml:space=\"preserve\">\n    <value>当前语言</value>\n  </data>\n  <data name=\"Settings\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/ShortcutGuide/ShortcutGuide/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Setting_Description_Overlay_Opacity\" xml:space=\"preserve\">\n    <value>Opacity of the Shortcut Guide's overlay background (%)</value>\n  </data>\n  <data name=\"Setting_Description_Theme\" xml:space=\"preserve\">\n    <value>Choose Shortcut Guide overlay color</value>\n  </data>\n  <data name=\"Setting_Description_Theme_Light\" xml:space=\"preserve\">\n    <value>Light</value>\n  </data>\n  <data name=\"Setting_Description_Theme_Dark\" xml:space=\"preserve\">\n    <value>Dark</value>\n  </data>\n  <data name=\"Setting_Description_Theme_System\" xml:space=\"preserve\">\n    <value>System default app mode</value>\n  </data>\n  <data name=\"Settings_Description\" xml:space=\"preserve\">\n    <value>Shows a help overlay with Windows shortcuts when the Windows key is pressed.</value>\n  </data>\n  <data name=\"Shortcut_Guide\" xml:space=\"preserve\">\n    <value>Shortcut Guide</value>\n  </data>\n  <data name=\"No_Action\" xml:space=\"preserve\">\n    <value>无动作</value>\n  </data>\n  <data name=\"Restore\" xml:space=\"preserve\">\n    <value>还原</value>\n  </data>\n  <data name=\"Snap_Right\" xml:space=\"preserve\">\n    <value>右贴靠</value>\n  </data>\n  <data name=\"Snap_Left\" xml:space=\"preserve\">\n    <value>左贴靠</value>\n  </data>\n  <data name=\"Snap_Upper_Right\" xml:space=\"preserve\">\n    <value>右上贴靠</value>\n  </data>\n  <data name=\"Snap_Upper_Left\" xml:space=\"preserve\">\n    <value>左上贴靠</value>\n  </data>\n  <data name=\"Snap_Lower_Right\" xml:space=\"preserve\">\n    <value>右下贴靠</value>\n  </data>\n  <data name=\"Snap_Lower_Left\" xml:space=\"preserve\">\n    <value>左下贴靠</value>\n  </data>\n  <data name=\"Minimize\" xml:space=\"preserve\">\n    <value>最小化</value>\n  </data>\n  <data name=\"Maximize\" xml:space=\"preserve\">\n    <value>最大化</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/Workspaces/WorkspacesEditor/Models/Project.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Drawing;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text.Json.Serialization;\nusing System.Threading.Tasks;\nusing System.Windows.Media.Imaging;\n\nusing ManagedCommon;\nusing WorkspacesEditor.Data;\nusing WorkspacesEditor.Utils;\n\nnamespace WorkspacesEditor.Models\n{\n    public class Project : INotifyPropertyChanged\n    {\n        [JsonIgnore]\n        public string EditorWindowTitle { get; set; }\n\n        public string Id { get; private set; }\n\n        private string _name;\n\n        public string Name\n        {\n            get => _name;\n\n            set\n            {\n                _name = value;\n                OnPropertyChanged(new PropertyChangedEventArgs(nameof(Name)));\n                OnPropertyChanged(new PropertyChangedEventArgs(nameof(CanBeSaved)));\n            }\n        }\n\n        public long CreationTime { get; } // in seconds\n\n        public long LastLaunchedTime { get; } // in seconds\n\n        public bool IsShortcutNeeded { get; set; }\n\n        public bool MoveExistingWindows { get; set; }\n\n        public string LastLaunched\n        {\n            get\n            {\n                string lastLaunched = WorkspacesEditor.Properties.Resources.LastLaunched + \"：\";\n                if (LastLaunchedTime == 0)\n                {\n                    return lastLaunched + WorkspacesEditor.Properties.Resources.Never;\n                }\n\n                const int SECOND = 1;\n                const int MINUTE = 60 * SECOND;\n                const int HOUR = 60 * MINUTE;\n                const int DAY = 24 * HOUR;\n                const int MONTH = 30 * DAY;\n\n                DateTime lastLaunchDateTime = new DateTime(1970, 1, 1, 0, 0, 0, 0, DateTimeKind.Utc).AddSeconds(LastLaunchedTime);\n\n                TimeSpan ts = DateTime.UtcNow - lastLaunchDateTime;\n                double delta = Math.Abs(ts.TotalSeconds);\n\n                if (delta < 1 * MINUTE)\n                {\n                    return lastLaunched + WorkspacesEditor.Properties.Resources.Recently;\n                }\n\n                if (delta < 2 * MINUTE)\n                {\n                    return lastLaunched + WorkspacesEditor.Properties.Resources.OneMinuteAgo;\n                }\n\n                if (delta < 45 * MINUTE)\n                {\n                    return lastLaunched + ts.Minutes + \" \" + WorkspacesEditor.Properties.Resources.MinutesAgo;\n                }\n\n                if (delta < 90 * MINUTE)\n                {\n                    return lastLaunched + WorkspacesEditor.Properties.Resources.OneHourAgo;\n                }\n\n                if (delta < 24 * HOUR)\n                {\n                    return lastLaunched + ts.Hours + \" \" + WorkspacesEditor.Properties.Resources.HoursAgo;\n                }\n\n                if (delta < 48 * HOUR)\n                {\n                    return lastLaunched + WorkspacesEditor.Properties.Resources.Yesterday;\n                }\n\n                if (delta < 30 * DAY)\n                {\n                    return lastLaunched + ts.Days + \" \" + WorkspacesEditor.Properties.Resources.DaysAgo;\n                }\n\n                if (delta < 12 * MONTH)\n                {\n                    int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30));\n                    return lastLaunched + (months <= 1 ? WorkspacesEditor.Properties.Resources.OneMonthAgo : months + \" \" + WorkspacesEditor.Properties.Resources.MonthsAgo);\n                }\n                else\n                {\n                    int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365));\n                    return lastLaunched + (years <= 1 ? WorkspacesEditor.Properties.Resources.OneYearAgo : years + \" \" + WorkspacesEditor.Properties.Resources.YearsAgo);\n                }\n            }\n        }\n\n        public bool CanBeSaved => Name.Length > 0 && Applications.Count > 0;\n\n        private bool _isRevertEnabled;\n\n        public bool IsRevertEnabled\n        {\n            get => _isRevertEnabled;\n            set\n            {\n                if (_isRevertEnabled != value)\n                {\n                    _isRevertEnabled = value;\n                    OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsRevertEnabled)));\n                }\n            }\n        }\n\n        private bool _isPopupVisible;\n\n        [JsonIgnore]\n        public bool IsPopupVisible\n        {\n            get => _isPopupVisible;\n\n            set\n            {\n                _isPopupVisible = value;\n                OnPropertyChanged(new PropertyChangedEventArgs(nameof(IsPopupVisible)));\n            }\n        }\n\n        public List<Application> Applications { get; set; }\n\n        public List<object> ApplicationsListed\n        {\n            get\n            {\n                List<object> applicationsListed = [];\n                ILookup<MonitorSetup, Application> apps = Applications.Where(x => !x.Minimized).ToLookup(x => x.MonitorSetup);\n                foreach (IGrouping<MonitorSetup, Application> appItem in apps.OrderBy(x => x.Key.MonitorDpiUnawareBounds.Left).ThenBy(x => x.Key.MonitorDpiUnawareBounds.Top))\n                {\n                    MonitorHeaderRow headerRow = new() { MonitorName = \"显示器 \" + appItem.Key.MonitorNumber, SelectString = Properties.Resources.SelectAllAppsOnMonitor.Replace(\"{0}\", appItem.Key.MonitorInfo) };\n                    applicationsListed.Add(headerRow);\n                    foreach (Application app in appItem)\n                    {\n                        applicationsListed.Add(app);\n                    }\n                }\n\n                IEnumerable<Application> minimizedApps = Applications.Where(x => x.Minimized);\n                if (minimizedApps.Any())\n                {\n                    MonitorHeaderRow headerRow = new() { MonitorName = Properties.Resources.Minimized_Apps, SelectString = Properties.Resources.SelectAllMinimizedApps };\n                    applicationsListed.Add(headerRow);\n                    foreach (Application app in minimizedApps)\n                    {\n                        applicationsListed.Add(app);\n                    }\n                }\n\n                return applicationsListed;\n            }\n        }\n\n        [JsonIgnore]\n        public string AppsCountString\n        {\n            get\n            {\n                int count = Applications.Count;\n                return count.ToString(CultureInfo.InvariantCulture) + \" \" + (count == 1 ? Properties.Resources.App : Properties.Resources.Apps);\n            }\n        }\n\n        public List<MonitorSetup> Monitors { get; }\n\n        public bool IsPositionChangedManually { get; set; } // telemetry\n\n        private BitmapImage _previewIcons;\n        private BitmapImage _previewImage;\n        private double _previewImageWidth;\n\n        public Project(Project selectedProject)\n        {\n            Id = selectedProject.Id;\n            Name = selectedProject.Name;\n            PreviewIcons = selectedProject.PreviewIcons;\n            PreviewImage = selectedProject.PreviewImage;\n            IsShortcutNeeded = selectedProject.IsShortcutNeeded;\n            MoveExistingWindows = selectedProject.MoveExistingWindows;\n\n            int screenIndex = 1;\n\n            Monitors = [];\n            foreach (MonitorSetup item in selectedProject.Monitors.OrderBy(x => x.MonitorDpiAwareBounds.Left).ThenBy(x => x.MonitorDpiAwareBounds.Top))\n            {\n                Monitors.Add(item);\n                screenIndex++;\n            }\n\n            Applications = [];\n            foreach (Application item in selectedProject.Applications)\n            {\n                Application newApp = new(item);\n                newApp.Parent = this;\n                newApp.InitializationFinished();\n                Applications.Add(newApp);\n            }\n        }\n\n        public Project(ProjectData.ProjectWrapper project)\n        {\n            Id = project.Id;\n            Name = project.Name;\n            CreationTime = project.CreationTime;\n            LastLaunchedTime = project.LastLaunchedTime;\n            IsShortcutNeeded = project.IsShortcutNeeded;\n            MoveExistingWindows = project.MoveExistingWindows;\n            Monitors = [];\n            Applications = [];\n\n            foreach (ProjectData.ApplicationWrapper app in project.Applications)\n            {\n                Models.Application newApp = new()\n                {\n                    Id = string.IsNullOrEmpty(app.Id) ? $\"{{{Guid.NewGuid()}}}\" : app.Id,\n                    AppName = app.Application,\n                    AppPath = app.ApplicationPath,\n                    AppTitle = app.Title,\n                    PwaAppId = string.IsNullOrEmpty(app.PwaAppId) ? string.Empty : app.PwaAppId,\n                    PackageFullName = app.PackageFullName,\n                    AppUserModelId = app.AppUserModelId,\n                    Parent = this,\n                    CommandLineArguments = app.CommandLineArguments,\n                    IsElevated = app.IsElevated,\n                    CanLaunchElevated = app.CanLaunchElevated,\n                    Maximized = app.Maximized,\n                    Minimized = app.Minimized,\n                    IsNotFound = false,\n                    Position = new Models.Application.WindowPosition()\n                    {\n                        Height = app.Position.Height,\n                        Width = app.Position.Width,\n                        X = app.Position.X,\n                        Y = app.Position.Y,\n                    },\n                    MonitorNumber = app.Monitor,\n                };\n                newApp.InitializationFinished();\n                Applications.Add(newApp);\n            }\n\n            foreach (ProjectData.MonitorConfigurationWrapper monitor in project.MonitorConfiguration)\n            {\n                System.Windows.Rect dpiAware = new(monitor.MonitorRectDpiAware.Left, monitor.MonitorRectDpiAware.Top, monitor.MonitorRectDpiAware.Width, monitor.MonitorRectDpiAware.Height);\n                System.Windows.Rect dpiUnaware = new(monitor.MonitorRectDpiUnaware.Left, monitor.MonitorRectDpiUnaware.Top, monitor.MonitorRectDpiUnaware.Width, monitor.MonitorRectDpiUnaware.Height);\n                Monitors.Add(new MonitorSetup(monitor.Id, monitor.InstanceId, monitor.MonitorNumber, monitor.Dpi, dpiAware, dpiUnaware));\n            }\n        }\n\n        public BitmapImage PreviewIcons\n        {\n            get => _previewIcons;\n\n            set\n            {\n                _previewIcons = value;\n                OnPropertyChanged(new PropertyChangedEventArgs(nameof(PreviewIcons)));\n            }\n        }\n\n        public BitmapImage PreviewImage\n        {\n            get => _previewImage;\n\n            set\n            {\n                _previewImage = value;\n                OnPropertyChanged(new PropertyChangedEventArgs(nameof(PreviewImage)));\n            }\n        }\n\n        public double PreviewImageWidth\n        {\n            get => _previewImageWidth;\n\n            set\n            {\n                _previewImageWidth = value;\n                OnPropertyChanged(new PropertyChangedEventArgs(nameof(PreviewImageWidth)));\n            }\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        public void OnPropertyChanged(PropertyChangedEventArgs e)\n        {\n            PropertyChanged?.Invoke(this, e);\n        }\n\n        public async void Initialize(Theme currentTheme)\n        {\n            PreviewIcons = await Task.Run(() => DrawHelper.DrawPreviewIcons(this));\n            Rectangle commonBounds = GetCommonBounds();\n            PreviewImage = await Task.Run(() => DrawHelper.DrawPreview(this, commonBounds, currentTheme));\n            PreviewImageWidth = commonBounds.Width / (commonBounds.Height * 1.2 / 200);\n        }\n\n        private Rectangle GetCommonBounds()\n        {\n            double minX = Monitors.First().MonitorDpiAwareBounds.Left;\n            double minY = Monitors.First().MonitorDpiAwareBounds.Top;\n            double maxX = Monitors.First().MonitorDpiAwareBounds.Right;\n            double maxY = Monitors.First().MonitorDpiAwareBounds.Bottom;\n            for (int monitorIndex = 1; monitorIndex < Monitors.Count; monitorIndex++)\n            {\n                Monitor monitor = Monitors[monitorIndex];\n                minX = Math.Min(minX, monitor.MonitorDpiAwareBounds.Left);\n                minY = Math.Min(minY, monitor.MonitorDpiAwareBounds.Top);\n                maxX = Math.Max(maxX, monitor.MonitorDpiAwareBounds.Right);\n                maxY = Math.Max(maxY, monitor.MonitorDpiAwareBounds.Bottom);\n            }\n\n            return new Rectangle((int)minX, (int)minY, (int)(maxX - minX), (int)(maxY - minY));\n        }\n\n        public void UpdateAfterLaunchAndEdit(Project projectBeforeLaunch)\n        {\n            Id = projectBeforeLaunch.Id;\n            Name = projectBeforeLaunch.Name;\n            IsRevertEnabled = true;\n            MoveExistingWindows = projectBeforeLaunch.MoveExistingWindows;\n            foreach (Application app in Applications)\n            {\n                var sameAppBefore = projectBeforeLaunch.Applications.Where(x => x.Id.Equals(app.Id, StringComparison.OrdinalIgnoreCase));\n                if (sameAppBefore.Any())\n                {\n                    var appBefore = sameAppBefore.FirstOrDefault();\n                    app.CommandLineArguments = appBefore.CommandLineArguments;\n                    app.IsElevated = appBefore.IsElevated;\n                }\n            }\n        }\n\n        internal void CloseExpanders()\n        {\n            foreach (Application app in Applications)\n            {\n                app.IsExpanded = false;\n            }\n        }\n\n        internal MonitorSetup GetMonitorForApp(Application app)\n        {\n            MonitorSetup monitorSetup = Monitors.Where(x => x.MonitorNumber == app.MonitorNumber).FirstOrDefault();\n            if (monitorSetup == null)\n            {\n                // monitors changed: try to determine monitor id based on middle point\n                int middleX = app.Position.X + (app.Position.Width / 2);\n                int middleY = app.Position.Y + (app.Position.Height / 2);\n                MonitorSetup monitorCandidate = Monitors.Where(x =>\n                    (x.MonitorDpiUnawareBounds.Left < middleX) &&\n                    (x.MonitorDpiUnawareBounds.Right > middleX) &&\n                    (x.MonitorDpiUnawareBounds.Top < middleY) &&\n                    (x.MonitorDpiUnawareBounds.Bottom > middleY)).FirstOrDefault();\n                if (monitorCandidate != null)\n                {\n                    app.MonitorNumber = monitorCandidate.MonitorNumber;\n                    return monitorCandidate;\n                }\n                else\n                {\n                    // monitors and even the app's area unknown, set the main monitor (which is closer to (0,0)) as the app's monitor\n                    monitorCandidate = Monitors.OrderBy(x => Math.Abs(x.MonitorDpiUnawareBounds.Left) + Math.Abs(x.MonitorDpiUnawareBounds.Top)).FirstOrDefault();\n                    if (monitorCandidate != null)\n                    {\n                        app.MonitorNumber = monitorCandidate.MonitorNumber;\n                        return monitorCandidate;\n                    }\n                    else\n                    {\n                        // no monitors defined at all.\n                        Logger.LogError($\"Wrong workspace setup. No monitors defined for the workspace: {Name}.\");\n                        return null;\n                    }\n                }\n            }\n\n            return monitorSetup;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/Workspaces/WorkspacesEditor/Properties/Resources.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AddBack\" xml:space=\"preserve\">\n    <value>取消删除</value>\n  </data>\n  <data name=\"Admin\" xml:space=\"preserve\">\n    <value>管理员权限</value>\n  </data>\n  <data name=\"App\" xml:space=\"preserve\">\n    <value>个应用</value>\n  </data>\n  <data name=\"Apps\" xml:space=\"preserve\">\n    <value>个应用</value>\n  </data>\n  <data name=\"App_name\" xml:space=\"preserve\">\n    <value>App name</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"Are_You_Sure\" xml:space=\"preserve\">\n    <value>Are you sure?</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"Are_You_Sure_Description\" xml:space=\"preserve\">\n    <value>Are you sure you want to delete this Workspace?</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"Args\" xml:space=\"preserve\">\n    <value>参数</value>\n    <comment>Arguments</comment>\n  </data>\n  <data name=\"Cancel\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"CliArguments\" xml:space=\"preserve\">\n    <value>命令行参数</value>\n  </data>\n  <data name=\"Created\" xml:space=\"preserve\">\n    <value>创建时间</value>\n  </data>\n  <data name=\"CreateWorkspace\" xml:space=\"preserve\">\n    <value>创建工作区</value>\n  </data>\n  <data name=\"CreateShortcut\" xml:space=\"preserve\">\n    <value>在桌面上创建快捷方式</value>\n  </data>\n  <data name=\"Custom\" xml:space=\"preserve\">\n    <value>自定义</value>\n  </data>\n  <data name=\"DaysAgo\" xml:space=\"preserve\">\n    <value>几天前</value>\n  </data>\n  <data name=\"DefaultWorkspaceNamePrefix\" xml:space=\"preserve\">\n    <value>工作区</value>\n  </data>\n  <data name=\"Delete\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"DeleteSelected\" xml:space=\"preserve\">\n    <value>删除选中应用</value>\n  </data>\n  <data name=\"Delete_Workspace_Dialog_Announce\" xml:space=\"preserve\">\n    <value>Delete Workspace dialog.</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"Edit\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"EditWorkspace\" xml:space=\"preserve\">\n    <value>编辑工作区</value>\n  </data>\n  <data name=\"Edit_Project_Open_Announce\" xml:space=\"preserve\">\n    <value>opened</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"Error_Parsing_Message\" xml:space=\"preserve\">\n    <value>无法解析工作区数据。</value>\n  </data>\n  <data name=\"Height\" xml:space=\"preserve\">\n    <value>高度</value>\n  </data>\n  <data name=\"HoursAgo\" xml:space=\"preserve\">\n    <value>小时前</value>\n  </data>\n  <data name=\"LastLaunched\" xml:space=\"preserve\">\n    <value>上次启动时间</value>\n  </data>\n  <data name=\"Launch\" xml:space=\"preserve\">\n    <value>启动</value>\n  </data>\n  <data name=\"LaunchAsAdmin\" xml:space=\"preserve\">\n    <value>管理员权限</value>\n  </data>\n  <data name=\"LaunchEdit\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"Launch_args\" xml:space=\"preserve\">\n    <value>Launch args</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"Left\" xml:space=\"preserve\">\n    <value>左侧坐标</value>\n    <comment>the left x coordinate</comment>\n  </data>\n  <data name=\"MainTitle\" xml:space=\"preserve\">\n    <value>工作区编辑器</value>\n  </data>\n  <data name=\"Maximized\" xml:space=\"preserve\">\n    <value>最大化</value>\n  </data>\n  <data name=\"Minimized\" xml:space=\"preserve\">\n    <value>最小化</value>\n  </data>\n  <data name=\"Minimized_Apps\" xml:space=\"preserve\">\n    <value>最小化到任务栏</value>\n  </data>\n  <data name=\"MinutesAgo\" xml:space=\"preserve\">\n    <value>分钟前</value>\n  </data>\n  <data name=\"MonthsAgo\" xml:space=\"preserve\">\n    <value>个月前</value>\n  </data>\n  <data name=\"MoveIfExist\" xml:space=\"preserve\">\n    <value>若应用已打开则仅移动窗口</value>\n  </data>\n  <data name=\"Name\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"Never\" xml:space=\"preserve\">\n    <value>从未启动</value>\n  </data>\n  <data name=\"New_Workspace\" xml:space=\"preserve\">\n    <value>New Workspace</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"NoWorkspacesMatch\" xml:space=\"preserve\">\n    <value>未找到符合条件的工作区。</value>\n  </data>\n  <data name=\"NotFoundTooltip\" xml:space=\"preserve\">\n    <value>找不到该应用</value>\n  </data>\n  <data name=\"No_Workspaces_Message\" xml:space=\"preserve\">\n    <value>尚未创建工作区。</value>\n  </data>\n  <data name=\"OneHourAgo\" xml:space=\"preserve\">\n    <value>1 小时前</value>\n  </data>\n  <data name=\"OneMinuteAgo\" xml:space=\"preserve\">\n    <value>1 分钟前</value>\n  </data>\n  <data name=\"OneMonthAgo\" xml:space=\"preserve\">\n    <value>1 个月前</value>\n  </data>\n  <data name=\"OneSecondAgo\" xml:space=\"preserve\">\n    <value>1 秒前</value>\n  </data>\n  <data name=\"OneYearAgo\" xml:space=\"preserve\">\n    <value>1 年前</value>\n  </data>\n  <data name=\"PinToTaskbar\" xml:space=\"preserve\">\n    <value>Pin Workspaces to taskbar</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"WorkspaceName\" xml:space=\"preserve\">\n    <value>工作区名称</value>\n  </data>\n  <data name=\"Workspaces\" xml:space=\"preserve\">\n    <value>工作区</value>\n  </data>\n  <data name=\"Recently\" xml:space=\"preserve\">\n    <value>刚才</value>\n  </data>\n  <data name=\"Revert\" xml:space=\"preserve\">\n    <value>撤销</value>\n  </data>\n  <data name=\"Save_Workspace\" xml:space=\"preserve\">\n    <value>保存工作区</value>\n  </data>\n  <data name=\"Search\" xml:space=\"preserve\">\n    <value>搜索</value>\n  </data>\n  <data name=\"SearchExplanation\" xml:space=\"preserve\">\n    <value>搜索工作区和应用</value>\n  </data>\n  <data name=\"SecondsAgo\" xml:space=\"preserve\">\n    <value>秒前</value>\n  </data>\n  <data name=\"SelectAllAppsOnMonitor\" xml:space=\"preserve\">\n    <value>选择所有位于 {0} 的应用</value>\n  </data>\n  <data name=\"SelectAllMinimizedApps\" xml:space=\"preserve\">\n    <value>选择所有最小化的应用</value>\n  </data>\n  <data name=\"SelectedAllInWorkspace\" xml:space=\"preserve\">\n    <value>Select all apps in Workspace</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"SnapshotDescription\" xml:space=\"preserve\">\n    <value>请调整好您的窗口位置，然后点击 \"捕捉\" 按钮。</value>\n  </data>\n  <data name=\"SnapshotWindowTitle\" xml:space=\"preserve\">\n    <value>快照创建器</value>\n  </data>\n  <data name=\"SortBy\" xml:space=\"preserve\">\n    <value>排序</value>\n  </data>\n  <data name=\"Take_Snapshot\" xml:space=\"preserve\">\n    <value>捕捉</value>\n  </data>\n  <data name=\"Top\" xml:space=\"preserve\">\n    <value>顶部坐标</value>\n    <comment>the top y coordinate</comment>\n  </data>\n  <data name=\"Width\" xml:space=\"preserve\">\n    <value>宽度</value>\n  </data>\n  <data name=\"WindowPosition\" xml:space=\"preserve\">\n    <value>窗口位置</value>\n  </data>\n  <data name=\"WriteArgs\" xml:space=\"preserve\">\n    <value>Write arguments here</value>\n    <comment>没用到</comment>\n  </data>\n  <data name=\"YearsAgo\" xml:space=\"preserve\">\n    <value>年前</value>\n  </data>\n  <data name=\"Yesterday\" xml:space=\"preserve\">\n    <value>昨天</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/Workspaces/WorkspacesLauncher/Resource.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Empty_file\" xml:space=\"preserve\">\n    <value>文件 {0} 为空。</value>\n  </data>\n  <data name=\"File_reading_error\" xml:space=\"preserve\">\n    <value>无法打开文件 {0}。</value>\n  </data>\n  <data name=\"Incorrect_args\" xml:space=\"preserve\">\n    <value>命令行参数不正确。</value>\n  </data>\n  <data name=\"Incorrect_file_error\" xml:space=\"preserve\">\n    <value>文件 {0} 不正确。</value>\n  </data>\n  <data name=\"Workspaces\" xml:space=\"preserve\">\n    <value>工作区</value>\n    <comment>Name of the module</comment>\n  </data>\n  <data name=\"Project_not_found\" xml:space=\"preserve\">\n    <value>找不到工作区 {0}。</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/Workspaces/WorkspacesLauncherUI/Properties/Resources.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"CancelLaunch\" xml:space=\"preserve\">\n    <value>取消启动</value>\n  </data>\n  <data name=\"Dismiss\" xml:space=\"preserve\">\n    <value>知道了</value>\n  </data>\n  <data name=\"LauncherWindowTitle\" xml:space=\"preserve\">\n    <value>您的工作区正在启动，请稍等...</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/Workspaces/WorkspacesSnapshotTool/Resource.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"DefaultProjectNamePrefix\" xml:space=\"preserve\">\n    <value>工作区</value>\n  </data>\n  <data name=\"Projects\" xml:space=\"preserve\">\n    <value>工作区</value>\n  </data>\n  <data name=\"System_Foreground_Elevated\" xml:space=\"preserve\">\n    <value>检测到一个以管理员权限运行的软件，工作区无法控制它。</value>\n  </data>\n  <data name=\"System_Foreground_Elevated_Dialog_Dont_Show_Again\" xml:space=\"preserve\">\n    <value>不再显示</value>\n  </data>\n  <data name=\"System_Foreground_Elevated_Learn_More\" xml:space=\"preserve\">\n    <value>了解更多</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/ZoomIt/ZoomIt/ZoomIt.rc",
    "content": "// Microsoft Visual C++ generated resource script.\n//\n#include \"resource.h\"\n\n// version.h and branding.h are different in the Sysinternals repository,\n// keep the includes as such, here.\n// From $(MSBuildThisFileDirectory)..\\..\\..\\common\\version\n#include \"version.h\"\n// From $(MSBuildThisFileDirectory)PowerToys\n#include \"branding.h\"\n\n#define APSTUDIO_READONLY_SYMBOLS\n/////////////////////////////////////////////////////////////////////////////\n//\n// Generated from the TEXTINCLUDE 2 resource.\n//\n#include \"winres.h\"\n\n/////////////////////////////////////////////////////////////////////////////\n#undef APSTUDIO_READONLY_SYMBOLS\n\n/////////////////////////////////////////////////////////////////////////////\n// Chinese (Simplified) resources\n\n#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\nLANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED\n#pragma code_page(936)\n\n#ifdef APSTUDIO_INVOKED\n/////////////////////////////////////////////////////////////////////////////\n//\n// TEXTINCLUDE\n//\n\n1 TEXTINCLUDE \nBEGIN\n    \"resource.h\\0\"\nEND\n\n2 TEXTINCLUDE \nBEGIN\n    \"#include \"\"winres.h\"\"\\r\\n\"\n    \"\\0\"\nEND\n\n3 TEXTINCLUDE \nBEGIN\n    \"#include \"\"binres.rc\"\"\\0\"\nEND\n\n#endif    // APSTUDIO_INVOKED\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Cursor\n//\n\nNULLCURSOR              CURSOR                  \"cursor1.cur\"\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Icon\n//\n\n// Icon with lowest ID value placed first to ensure application icon\n// remains consistent on all systems.\nAPPICON                 ICON                    \"appicon.ico\"\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Version\n//\n\nVS_VERSION_INFO VERSIONINFO\n FILEVERSION FILE_VERSION\n PRODUCTVERSION PRODUCT_VERSION\n FILEFLAGSMASK 0x3fL\n#ifdef _DEBUG\n FILEFLAGS 0x1L\n#else\n FILEFLAGS 0x0L\n#endif\n FILEOS 0x40004L\n FILETYPE 0x1L\n FILESUBTYPE 0x0L\nBEGIN\n    BLOCK \"StringFileInfo\"\n    BEGIN\n        BLOCK \"040904b0\"\n        BEGIN\n            VALUE \"CompanyName\", COMPANY_NAME\n            VALUE \"FileDescription\", FILE_DESCRIPTION\n            VALUE \"FileVersion\", FILE_VERSION_STRING\n            VALUE \"InternalName\", INTERNAL_NAME\n            VALUE \"LegalCopyright\", COPYRIGHT_NOTE\n            VALUE \"OriginalFilename\", ORIGINAL_FILENAME\n            VALUE \"ProductName\", ZOOMIT_PRODUCT_NAME\n            VALUE \"ProductVersion\", PRODUCT_VERSION_STRING\n        END\n    END\n    BLOCK \"VarFileInfo\"\n    BEGIN\n        VALUE \"Translation\", 0x409, 1200\n    END\nEND\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Dialog\n//\n\nOPTIONS DIALOGEX 0, 0, 279, 325\nSTYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CLIPSIBLINGS | WS_CAPTION | WS_SYSMENU\nEXSTYLE WS_EX_CONTROLPARENT\nCAPTION \"ZoomIt - Sysinternals: www.sysinternals.com\"\nFONT 8, \"MS Shell Dlg\", 0, 0, 0x0\nBEGIN\n    DEFPUSHBUTTON   \"ȷ\",IDOK,166,306,50,14\n    PUSHBUTTON      \"ȡ\",IDCANCEL,223,306,50,14\n    LTEXT           \"ZoomIt v9.0\",IDC_VERSION,42,7,73,10\n    LTEXT           \"Ȩ 17 2006-2024 Mark Russinovich\",IDC_COPYRIGHT,42,17,176,8\n    CONTROL         \"<a HREF=\"\"https://www.sysinternals.com\"\">Sysinternals - www.sysinternals.com</a>\",IDC_LINK,\n                    \"SysLink\",WS_TABSTOP,42,26,150,9\n    ICON            \"APPICON\",IDC_STATIC,12,9,20,20\n    CONTROL         \"ʾͼ\",IDC_SHOW_TRAY_ICON,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,13,295,105,10\n    CONTROL         \"\",IDC_TAB,\"SysTabControl32\",TCS_MULTILINE | WS_TABSTOP,8,46,265,245\n    CONTROL         \"\",IDC_AUTOSTART,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,13,309,122,10\nEND\n\nADVANCED_BREAK DIALOGEX 0, 0, 209, 219\nSTYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU\nCAPTION \"ʱ߼\"\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    CONTROL         \"ʱ:\",IDC_CHECK_SOUND_FILE,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,3,11,98,10,WS_EX_RIGHT\n    EDITTEXT        IDC_SOUND_FILE,61,38,125,12,ES_AUTOHSCROLL | ES_READONLY\n    PUSHBUTTON      \"&...\",IDC_SOUND_BROWSE,187,38,13,11\n    COMBOBOX        IDC_OPACITY,62,58,38,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\n    CONTROL         \"\",IDC_TIMER_POS1,\"Button\",BS_AUTORADIOBUTTON,63,78,10,10\n    CONTROL         \"\",IDC_TIMER_POS2,\"Button\",BS_AUTORADIOBUTTON,79,78,10,10\n    CONTROL         \"\",IDC_TIMER_POS3,\"Button\",BS_AUTORADIOBUTTON,97,78,10,10\n    CONTROL         \"\",IDC_TIMER_POS4,\"Button\",BS_AUTORADIOBUTTON,63,93,10,10\n    CONTROL         \"\",IDC_TIMER_POS5,\"Button\",BS_AUTORADIOBUTTON,79,93,10,10\n    CONTROL         \"\",IDC_TIMER_POS6,\"Button\",BS_AUTORADIOBUTTON,97,93,10,10\n    CONTROL         \"\",IDC_TIMER_POS7,\"Button\",BS_AUTORADIOBUTTON,63,108,10,10\n    CONTROL         \"\",IDC_TIMER_POS8,\"Button\",BS_AUTORADIOBUTTON,79,108,10,10\n    CONTROL         \"\",IDC_TIMER_POS9,\"Button\",BS_AUTORADIOBUTTON,97,108,10,10\n    CONTROL         \"ʾͼƬ:\",IDC_CHECK_BACKGROUND_FILE,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,3,122,99,10,WS_EX_RIGHT\n    CONTROL         \"ʹñ䰵Ļͼ\",IDC_STATIC_DESKTOP_BACKGROUND,\n                    \"Button\",BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,46,135,125,10\n    CONTROL         \"ʹԶͼļ\",IDC_STATIC_BACKGROUND_FILE,\n                    \"Button\",BS_AUTORADIOBUTTON | WS_TABSTOP,46,149,109,10\n    EDITTEXT        IDC_BACKGROUND_FILE,62,164,125,12,ES_AUTOHSCROLL | ES_READONLY\n    PUSHBUTTON      \"&...\",IDC_BACKGROUND_BROWSE,188,164,13,11\n    CONTROL         \"ȫ:\",IDC_CHECK_BACKGROUND_STRETCH,\"Button\",BS_AUTOCHECKBOX | WS_TABSTOP,58,180,67,10,WS_EX_RIGHT\n    DEFPUSHBUTTON   \"ȷ\",IDOK,97,201,50,14\n    PUSHBUTTON      \"ȡ\",IDCANCEL,150,201,50,14\n    LTEXT           \"Ƶļ:\",IDC_STATIC_SOUND_FILE,61,26,56,8\n    LTEXT           \"ڲ͸:\",IDC_STATIC,8,59,48,8\n    LTEXT           \"ʱʾλ:\",IDC_STATIC,8,77,48,8\n    CONTROL         \"\",IDC_STATIC,\"Static\",SS_BLACKFRAME | SS_SUNKEN,7,196,193,1,WS_EX_CLIENTEDGE\nEND\n\nZOOM DIALOGEX 0, 0, 260, 158\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    CONTROL         \"\",IDC_HOTKEY,\"msctls_hotkey32\",WS_BORDER | WS_TABSTOP,59,57,80,12\n    LTEXT           \"¿ݼŴ֮󣬹ֻ·ŴС Esc Ҽ˳Ŵ\",IDC_STATIC,7,6,246,26\n    LTEXT           \"Ŵݼ:\",IDC_STATIC,7,59,51,8\n    CONTROL         \"\",IDC_ZOOM_SLIDER,\"msctls_trackbar32\",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,53,104,150,15,WS_EX_TRANSPARENT\n    LTEXT           \"ĬϷŴ:\",IDC_STATIC,7,91,215,10\n    LTEXT           \"1.25\",IDC_STATIC,52,122,16,8\n    LTEXT           \"1.5\",IDC_STATIC,82,122,12,8\n    LTEXT           \"1.75\",IDC_STATIC,108,122,16,8\n    LTEXT           \"2.0\",IDC_STATIC,138,122,12,8\n    LTEXT           \"3.0\",IDC_STATIC,164,122,12,8\n    LTEXT           \"4.0\",IDC_STATIC,190,122,12,8\n    CONTROL         \"ŴС:\",IDC_ANIMATE_ZOOM,\"Button\",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,7,74,116,10\n    LTEXT           \" Ctrl+C ƽͼCtrl+S ͼCtrl+Shift+C ѡƣCtrl+Shift+S ѡ档\",IDC_STATIC,7,34,246,17\nEND\n\nDRAW DIALOGEX 0, 0, 260, 228\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    LTEXT           \"Ŵ֮󣬵ʼͼҼ˳ͼ Ctrl+Z أ E գոƵĻ롣\",IDC_STATIC,7,7,246,24\n    LTEXT           \"ϸ\",IDC_PEN_CONTROL,7,38,40,8\n    LTEXT           \" Ctrl+ֻ· ʴϸ\",IDC_STATIC,19,48,233,16\n    LTEXT           \"ɫ\",IDC_COLORS,7,70,21,8\n    LTEXT           \" R ɫG ɫB ɫO ɫY ɫP ɫ\",IDC_STATIC,19,80,233,16\n    LTEXT           \"Ч\",IDC_HIGHLIGHT_AND_BLUR,7,102,58,8\n    LTEXT           \" Shift+ɫ ɶӦİ͸߹ɫ X ģShift+X Ǹǿģ\",IDC_STATIC,19,113,233,16\n    LTEXT           \"״\",IDC_SHAPES,7,134,23,8\n    LTEXT           \"ס Shift ֱߣס Ctrl Σס Tab Բס Ctrl+Shift ͷ\",IDC_STATIC,19,144,233,16\n    LTEXT           \"\",IDC_SCREEN,7,166,22,8\n    LTEXT           \" W ȫɰɫK ɫ֧ͬ Ctrl+C ƺ Ctrl+S ȡ\",IDC_STATIC,19,176,233,24\n    CONTROL         \"\",IDC_DRAW_HOTKEY,\"msctls_hotkey32\",WS_BORDER | WS_TABSTOP,73,207,80,12\n    LTEXT           \"ͼݼ:\",IDC_STATIC,7,210,63,11\nEND\n\nTYPE DIALOGEX 0, 0, 260, 104\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    LTEXT           \"ڻͼʱ T ıShift+T Ҷı Esc 򵥻ı롣ֻ·ıС\",IDC_STATIC,7,7,246,32\n    LTEXT           \"ıɫǵǰĻɫ\",IDC_STATIC,7,47,211,9\n    PUSHBUTTON      \"(&F)\",IDC_FONT,112,69,41,14\n    GROUPBOX        \"\",IDC_TEXT_FONT,8,61,99,28\nEND\n\nBREAK DIALOGEX 0, 0, 260, 123\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    CONTROL         \"\",IDC_BREAK_HOTKEY,\"msctls_hotkey32\",WS_BORDER | WS_TABSTOP,52,67,80,12\n    EDITTEXT        IDC_TIMER,31,86,31,13,ES_RIGHT | ES_AUTOHSCROLL | ES_NUMBER\n    CONTROL         \"\",IDC_SPIN_TIMER,\"msctls_updown32\",UDS_SETBUDDYINT | UDS_ALIGNRIGHT | UDS_AUTOBUDDY | UDS_ARROWKEYS | UDS_NOTHOUSANDS,45,86,11,12\n    LTEXT           \"\",IDC_STATIC,67,88,25,8\n    PUSHBUTTON      \"߼(&A)\",IDC_ADVANCED_BREAK,212,102,41,14\n    LTEXT           \"ݼʹ̲˵ʼʱʱ䣬 Esc ˳;ʹ Alt+Tab лڣͼԷؼʱڡ\",IDC_STATIC,7,7,246,33\n    LTEXT           \"ʱݼ:\",IDC_STATIC,7,70,39,8\n    LTEXT           \"ʱ:\",IDC_STATIC,7,88,27,8\n    LTEXT           \"ʱɫ԰ɫлǻͼı塣\",IDC_STATIC,7,45,219,20\n    CONTROL         \"ʱʾʱ:\",IDC_CHECK_SHOW_EXPIRED,\n                    \"Button\",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,8,104,132,10\nEND\n\n1543 DIALOGEX 100, 50, 216, 131\nSTYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU\nCAPTION \"ZoomIt \"\nFONT 8, \"MS Shell Dlg\", 0, 0, 0x0\nBEGIN\n    LTEXT           \"(&F):\",1088,6,0,40,9\n    COMBOBOX        1136,6,10,94,64,CBS_SIMPLE | CBS_OWNERDRAWFIXED | CBS_AUTOHSCROLL | CBS_SORT | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP\n    LTEXT           \"(&Y):\",1089,108,0,44,9\n    COMBOBOX        1137,108,10,64,64,CBS_SIMPLE | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP\n    LTEXT           \"ֺ(&S):\",1090,179,0,30,9\n    COMBOBOX        1138,179,10,32,64,CBS_SIMPLE | CBS_OWNERDRAWFIXED | CBS_SORT | CBS_HASSTRINGS | CBS_DISABLENOSCROLL | WS_VSCROLL | WS_TABSTOP\n    DEFPUSHBUTTON   \"ȷ\",IDOK,166,94,45,14,WS_GROUP\n    PUSHBUTTON      \"ȡ\",IDCANCEL,166,111,45,14,WS_GROUP\n    GROUPBOX        \"Sample\",1073,7,75,143,51,WS_GROUP\n    CTEXT           \"AaBbYyZz\",1092,16,88,127,31,SS_NOPREFIX | NOT WS_VISIBLE\nEND\n\nLIVEZOOM DIALOGEX 0, 0, 260, 134\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    CONTROL         \"\",IDC_LIVE_HOTKEY,\"msctls_hotkey32\",WS_BORDER | WS_TABSTOP,69,108,80,12\n    LTEXT           \"ģʽ´ܶҪ Windows 7\",IDC_STATIC,7,7,246,18\n    LTEXT           \"ʵʱŴݼ:\",IDC_STATIC,7,110,62,8\n    LTEXT           \"ݼ˳ʵʱŴ\",IDC_STATIC,7,94,218,13\n    LTEXT           \" Ctrl+· ŴС ͼݼ ử濪ʼͼ갴 Esc صʵʱС\",IDC_STATIC,7,30,246,27\n    LTEXT           \" Shift+ʵʱŴݼ ʼʵʱͼ治ᶳᣬ Esc ء\",IDC_STATIC,7,62,246,32\nEND\n\nRECORD DIALOGEX 0, 0, 260, 169\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    CONTROL         \"\",IDC_RECORD_HOTKEY,\"msctls_hotkey32\",WS_BORDER | WS_TABSTOP,61,96,80,12\n    LTEXT           \"¼ݼ:\",IDC_STATIC,7,98,54,8\n    LTEXT           \"ݼԿʼ¼ȫٰһ¿Խ¼\",IDC_STATIC,7,7,246,28\n    LTEXT           \"¼Ҫ Windows 10 汾 1903 ϡ\",IDC_STATIC,7,77,246,19\n    LTEXT           \"ֱʱ:\",IDC_STATIC,7,115,54,8\n    COMBOBOX        IDC_RECORD_SCALING,61,114,26,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OEMCONVERT | CBS_SORT | WS_VSCROLL | WS_TABSTOP\n    LTEXT           \"ˢ:\",IDC_STATIC,119,115,44,8,NOT WS_VISIBLE\n    COMBOBOX        IDC_RECORD_FRAME_RATE,166,114,42,30,CBS_DROPDOWNLIST | CBS_AUTOHSCROLL | CBS_OEMCONVERT | CBS_SORT | NOT WS_VISIBLE | WS_VSCROLL | WS_TABSTOP\n    LTEXT           \" Shift+¼ݼ Կѡ¼ơ\",IDC_STATIC,7,32,246,19\n    LTEXT           \" Alt+¼ݼ ¼Ƶǰڡ\",IDC_STATIC,7,55,246,19\n    CONTROL         \"¼˷Ƶ(&C):\",IDC_CAPTURE_AUDIO,\"Button\",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,7,137,83,10\n    COMBOBOX        IDC_MICROPHONE,81,152,172,30,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP\n    LTEXT           \"˷:\",IDC_STATIC,32,154,47,8\nEND\n\nSNIP DIALOGEX 0, 0, 260, 68\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    CONTROL         \"\",IDC_SNIP_HOTKEY,\"msctls_hotkey32\",WS_BORDER | WS_TABSTOP,55,32,80,12\n    LTEXT           \"ͼݼ:\",IDC_STATIC,7,33,45,8\n    LTEXT           \" ͼݼ ͼƣ Shift+ͼݼ ͼ档\",IDC_STATIC,7,7,246,19\nEND\n\nDEMOTYPE DIALOGEX 0, 0, 259, 249\nSTYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU\nFONT 8, \"MS Shell Dlg\", 400, 0, 0x1\nBEGIN\n    CONTROL         \"\",IDC_DEMOTYPE_HOTKEY,\"msctls_hotkey32\",WS_BORDER | WS_TABSTOP,74,154,80,12\n    LTEXT           \"Զֿݼ:\",IDC_STATIC,7,157,63,8\n    PUSHBUTTON      \"&...\",IDC_DEMOTYPE_BROWSE,231,137,16,13\n    CONTROL         \"\",IDC_DEMOTYPE_SPEED_SLIDER,\"msctls_trackbar32\",TBS_AUTOTICKS | TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,52,202,150,11,WS_EX_TRANSPARENT\n    CONTROL         \"Զģʽ:\",IDC_DEMOTYPE_USER_DRIVEN,\"Button\",BS_AUTOCHECKBOX | BS_LEFTTEXT | WS_TABSTOP,7,173,88,10\n    LTEXT           \"ٶ:\",IDC_STATIC,7,189,215,10\n    LTEXT           \"\",IDC_DEMOTYPE_STATIC1,51,213,18,8\n    LTEXT           \"\",IDC_DEMOTYPE_STATIC2,186,213,17,8\n    EDITTEXT        IDC_DEMOTYPE_FILE,44,137,187,12,ES_AUTOHSCROLL | ES_READONLY\n    LTEXT           \"ļ:\",IDC_STATIC,7,139,32,8\n    LTEXT           \"ļ֮󣬽¼ļصͷ Shift+Զֿݼ صһΡ\",IDC_STATIC,7,108,248,24\n    LTEXT           \"ѡһļΪıݼԶһֵشҲԴӼııҪ [start] ͷ\",IDC_STATIC,7,7,248,24\n    LTEXT           \"  -  [pause:n] Եȴ n 롣\",IDC_STATIC,19,34,212,11\n    LTEXT           \"ĬԶԶģʽǾֶһ¼һ֡ԶֵĹУ̽ᱻơ\",IDC_STATIC,7,68,248,16\n    LTEXT           \"Զģʽ£һ֮ҪոơȫԶģʽ»Զơ\",IDC_STATIC,7,88,248,16\n    LTEXT           \"-  [paste]  [/paste] Ĳֿһճ\",IDC_STATIC,23,45,178,8\n    LTEXT           \"-  [enter][up][down][left][right] ʾسҰ\",IDC_STATIC,23,56,211,8\nEND\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// DESIGNINFO\n//\n\n#ifdef APSTUDIO_INVOKED\nGUIDELINES DESIGNINFO\nBEGIN\n    \"OPTIONS\", DIALOG\n    BEGIN\n        RIGHTMARGIN, 273\n        BOTTOMMARGIN, 320\n    END\n\n    \"ADVANCED_BREAK\", DIALOG\n    BEGIN\n        RIGHTMARGIN, 207\n        BOTTOMMARGIN, 215\n    END\n\n    \"ZOOM\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 253\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 151\n    END\n\n    \"DRAW\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 253\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 221\n    END\n\n    \"TYPE\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 253\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 97\n    END\n\n    \"BREAK\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 253\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 116\n    END\n\n    1543, DIALOG\n    BEGIN\n        RIGHTMARGIN, 211\n        BOTTOMMARGIN, 127\n    END\n\n    \"LIVEZOOM\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 253\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 127\n    END\n\n    \"RECORD\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 253\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 164\n    END\n\n    \"SNIP\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 253\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 61\n    END\n\n    \"DEMOTYPE\", DIALOG\n    BEGIN\n        LEFTMARGIN, 7\n        RIGHTMARGIN, 255\n        TOPMARGIN, 7\n        BOTTOMMARGIN, 205\n    END\nEND\n#endif    // APSTUDIO_INVOKED\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// Accelerator\n//\n\nACCELERATORS ACCELERATORS\nBEGIN\n    \"C\",            IDC_COPY,               VIRTKEY, CONTROL, NOINVERT\n    \"S\",            IDC_SAVE,               VIRTKEY, CONTROL, NOINVERT\n    \"C\",            IDC_COPY_CROP,           VIRTKEY, SHIFT, CONTROL, NOINVERT\n    \"S\",            IDC_SAVE_CROP,           VIRTKEY, SHIFT, CONTROL, NOINVERT\nEND\n\n\n/////////////////////////////////////////////////////////////////////////////\n//\n// AFX_DIALOG_LAYOUT\n//\n\nOPTIONS AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nLIVEZOOM AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nDRAW AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nRECORD AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nTYPE AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nZOOM AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nSNIP AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nBREAK AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\nDEMOTYPE AFX_DIALOG_LAYOUT\nBEGIN\n    0\nEND\n\n#endif    // English (United States) resources\n/////////////////////////////////////////////////////////////////////////////\n\n\n\n#ifndef APSTUDIO_INVOKED\n/////////////////////////////////////////////////////////////////////////////\n//\n// Generated from the TEXTINCLUDE 3 resource.\n//\n#include \"binres.rc\"\n/////////////////////////////////////////////////////////////////////////////\n#endif    // not APSTUDIO_INVOKED\n\n"
  },
  {
    "path": "PowerToys/src/modules/ZoomIt/ZoomIt/Zoomit.cpp",
    "content": "﻿//============================================================================\n//\n// Zoomit\n// Copyright (C) Mark Russinovich\n// Sysinternals - www.sysinternals.com\n//\n// Screen zoom and annotation tool.\n//\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n//============================================================================\n#include \"pch.h\"\n\n#include \"zoomit.h\"\n#include \"Utility.h\"\n#include \"WindowsVersions.h\"\n#include \"ZoomItSettings.h\"\n\n#ifdef __ZOOMIT_POWERTOYS__\n#include <common/interop/shared_constants.h>\n#include <common/utils/ProcessWaiter.h>\n#include <common/utils/process_path.h>\n\n#include \"../ZoomItModuleInterface/trace.h\"\n#include <common/Telemetry/EtwTrace/EtwTrace.h>\n#include <common/logger/logger.h>\n#include <common/utils/logger_helper.h>\n#include <common/utils/winapi_error.h>\n#include <common/utils/gpo.h>\n#endif // __ZOOMIT_POWERTOYS__\n\nnamespace winrt\n{\n    using namespace Windows::Foundation;\n    using namespace Windows::Graphics;\n    using namespace Windows::Graphics::Capture;\n    using namespace Windows::Graphics::Imaging;\n    using namespace Windows::Storage;\n    using namespace Windows::UI::Composition;\n    using namespace Windows::Storage::Pickers;\n    using namespace Windows::System;\n    using namespace Windows::Devices::Enumeration;\n}\n\nnamespace util\n{\n    using namespace robmikh::common::uwp;\n    using namespace robmikh::common::desktop;\n}\n\n// This workaround keeps live zoom enabled after zooming out at level 1 (not zoomed) and disables\n// live zoom when recording is stopped.\n#define WINDOWS_CURSOR_RECORDING_WORKAROUND 1\n\nHINSTANCE\t\tg_hInstance;\n\nCOLORREF\tg_CustomColors[16];\n\n#define ZOOM_HOTKEY\t\t\t\t0\n#define DRAW_HOTKEY\t\t\t\t1\n#define BREAK_HOTKEY\t\t\t2\n#define LIVE_HOTKEY\t\t\t\t3\n#define LIVE_DRAW_HOTKEY\t\t    4\n#define RECORD_HOTKEY\t\t    5\n#define RECORD_CROP_HOTKEY\t    6\n#define RECORD_WINDOW_HOTKEY\t    7\n#define SNIP_HOTKEY\t\t\t    8\n#define SNIP_SAVE_HOTKEY\t\t    9\n#define DEMOTYPE_HOTKEY\t\t    10\n#define DEMOTYPE_RESET_HOTKEY    11\n\n#define ZOOM_PAGE\t  0\n#define LIVE_PAGE\t  1\n#define DRAW_PAGE\t  2\n#define TYPE_PAGE\t  3\n#define DEMOTYPE_PAGE 4\n#define BREAK_PAGE\t  5\n#define RECORD_PAGE\t  6\n#define SNIP_PAGE\t  7\n\nOPTION_TABS g_OptionsTabs[] = {\n    { _T(\"Zoom\"), NULL },\n    { _T(\"LiveZoom\"), NULL },\n    { _T(\"Draw\"), NULL },\n    { _T(\"Type\"), NULL },\n    { _T(\"DemoType\"), NULL },\n    { _T(\"Break\"), NULL },\n    { _T(\"Record\"), NULL },\n    { _T(\"Snip\"), NULL }\n};\n\nfloat g_ZoomLevels[] = {\n    1.25,\n    1.50,\n    1.75,\n    2.00,\n    3.00,\n    4.00\n};\n\nDWORD g_FramerateOptions[] = {\n    30,\n    60\n};\n\n//\n// For typing mode\n//\ntypedef enum {\n    TypeModeOff = 0,\n    TypeModeLeftJustify,\n    TypeModeRightJustify\n} TypeModeState;\n\nconst DWORD CURSOR_ARM_LENGTH = 4;\n\nconst float NORMAL_BLUR_RADIUS = 20;\nconst float STRONG_BLUR_RADIUS = 40;\n\nDWORD\tg_ToggleMod;\nDWORD\tg_LiveZoomToggleMod;\nDWORD\tg_DrawToggleMod;\nDWORD\tg_BreakToggleMod; \nDWORD\tg_DemoTypeToggleMod;\nDWORD\tg_RecordToggleMod;\nDWORD   g_SnipToggleMod;\n\nBOOLEAN\tg_ZoomOnLiveZoom = FALSE;\nDWORD\tg_PenWidth = PEN_WIDTH;\nfloat   g_BlurRadius = NORMAL_BLUR_RADIUS;\nHWND\thWndOptions = NULL;\nBOOLEAN\tg_DrawPointer = FALSE;\nBOOLEAN g_PenDown = FALSE;\nBOOLEAN g_PenInverted = FALSE;\nDWORD\tg_OsVersion;\nHWND\tg_hWndLiveZoom = NULL;\nHWND    g_hWndLiveZoomMag = NULL;\nHWND\tg_hWndMain;\nint\t\tg_AlphaBlend = 0x80;\nBOOL\tg_fullScreenWorkaround = FALSE;\nbool\tg_bSaveInProgress = false;\nstd::wstring\tg_TextBuffer;\n// This is useful in the context of right-justified text only.\nstd::list<std::wstring> g_TextBufferPreviousLines;\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\nbool\tg_LiveZoomLevelOne = false;\n#endif\n\n// True if ZoomIt was started by PowerToys instead of standalone.\nBOOLEAN g_StartedByPowerToys = FALSE;\nBOOLEAN g_running = TRUE;\n\n// Screen recording globals\n#define DEFAULT_RECORDING_FILE\t\tL\"录屏.mp4\"\nBOOL\tg_RecordToggle = FALSE;\nBOOL\tg_RecordCropping = FALSE;\nSelectRectangle g_SelectRectangle;\nstd::wstring\tg_RecordingSaveLocation;\nwinrt::IDirect3DDevice\tg_RecordDevice{ nullptr };\nstd::shared_ptr<VideoRecordingSession> g_RecordingSession = nullptr;\n\ntype_pGetMonitorInfo\t\tpGetMonitorInfo;\ntype_MonitorFromPoint\t\tpMonitorFromPoint;\ntype_pSHAutoComplete\t\tpSHAutoComplete;\ntype_pSetLayeredWindowAttributes\tpSetLayeredWindowAttributes;\ntype_pSetProcessDPIAware\tpSetProcessDPIAware;\ntype_pMagSetWindowSource\tpMagSetWindowSource;\ntype_pMagSetWindowTransform pMagSetWindowTransform;\ntype_pMagSetFullscreenTransform pMagSetFullscreenTransform;\ntype_pMagSetInputTransform\tpMagSetInputTransform;\ntype_pMagShowSystemCursor\tpMagShowSystemCursor;\ntype_pMagSetWindowFilterList pMagSetWindowFilterList;\ntype_pMagInitialize\t\t\tpMagInitialize;\ntype_pDwmIsCompositionEnabled\tpDwmIsCompositionEnabled;\ntype_pGetPointerType\t\tpGetPointerType;\ntype_pGetPointerPenInfo pGetPointerPenInfo;\ntype_pSystemParametersInfoForDpi pSystemParametersInfoForDpi;\ntype_pGetDpiForWindow\t\tpGetDpiForWindow;\n\ntype_pSHQueryUserNotificationState\tpSHQueryUserNotificationState;\n\ntype_pCreateDirect3D11DeviceFromDXGIDevice\t\tpCreateDirect3D11DeviceFromDXGIDevice;\ntype_pCreateDirect3D11SurfaceFromDXGISurface\tpCreateDirect3D11SurfaceFromDXGISurface;\ntype_pD3D11CreateDevice \t\t\t\t\t\tpD3D11CreateDevice;\n\nClassRegistry\treg( _T(\"Software\\\\Sysinternals\\\\\") APPNAME );\n\nComputerGraphicsInit\tg_GraphicsInit;\n\n\n//----------------------------------------------------------------------------\n//\n// Saves specified filePath to clipboard. \n//\n//----------------------------------------------------------------------------\nbool SaveToClipboard( const WCHAR* filePath, HWND hwnd )\n{\n    if( filePath == NULL || hwnd == NULL || wcslen( filePath ) == 0 )\n    {\n        return false;\n    }\n\n    size_t size = sizeof(DROPFILES) + sizeof(WCHAR) * ( _tcslen( filePath ) + 1 ) + sizeof(WCHAR);\n\n    HDROP hDrop   = static_cast<HDROP>(GlobalAlloc( GHND, size ));\n    if (hDrop == NULL)\n    {\n        return false; \n    }\n\n    DROPFILES* dFiles = static_cast<DROPFILES*>(GlobalLock( hDrop ));\n    if (dFiles == NULL)\n    {\n        GlobalFree( hDrop );\n        return false; \n    }\n\n    dFiles->pFiles = sizeof(DROPFILES);\n    dFiles->fWide = TRUE; \n\n    wcscpy( reinterpret_cast<WCHAR*>(& dFiles[1]), filePath);\n    GlobalUnlock( hDrop );\n\n    if( OpenClipboard( hwnd ) )\n    {\n        EmptyClipboard();\n        SetClipboardData( CF_HDROP, hDrop );\n        CloseClipboard();\n    }\n\n    GlobalFree( hDrop );\n\n    return true;\n}\n\n//----------------------------------------------------------------------\n//\n// OutputDebug\n//\n//----------------------------------------------------------------------\nvoid OutputDebug(const TCHAR* format, ...)\n{\n#if _DEBUG\n    TCHAR\tmsg[1024];\n    va_list\tva;\n\n#ifdef _MSC_VER\n// For some reason, ARM64 Debug builds causes an analyzer error on va_start: \"error C26492: Don't use const_cast to cast away const or volatile (type.3).\"\n#pragma warning(push)\n#pragma warning(disable : 26492)\n#endif\n    va_start(va, format);\n#ifdef _MSC_VER\n#pragma warning(pop)\n#endif\n    _vstprintf_s(msg, format, va);\n    va_end(va);\n\n    OutputDebugString(msg);\n#endif\n}\n\n//----------------------------------------------------------------------------\n//\n// InitializeFonts\n//\n// Return a bold equivalent of either a DPI aware font face for GUI text or\n// just the stock object for DEFAULT_GUI_FONT.\n//\n//----------------------------------------------------------------------------\nvoid InitializeFonts( HWND hwnd, HFONT *bold )\n{\n    LOGFONT logFont;\n    bool haveLogFont = false;\n\n    if( *bold )\n    {\n        DeleteObject( *bold );\n        *bold = nullptr;\n    }\n\n    if( pSystemParametersInfoForDpi && pGetDpiForWindow )\n    {\n        NONCLIENTMETRICSW metrics{};\n        metrics.cbSize = sizeof( metrics );\n\n        if( pSystemParametersInfoForDpi( SPI_GETNONCLIENTMETRICS, sizeof( metrics ), &metrics, 0, pGetDpiForWindow( hwnd ) ) )\n        {\n            CopyMemory( &logFont, &metrics.lfMessageFont, sizeof( logFont ) );\n            haveLogFont = true;\n        }\n    }\n\n    if( !haveLogFont )\n    {\n        auto normal = static_cast<HFONT>(GetStockObject( DEFAULT_GUI_FONT ));\n        GetObject( normal, sizeof( logFont ), &logFont );\n        haveLogFont = true; // for correctness\n    }\n\n    logFont.lfWeight = FW_BOLD;\n    *bold = CreateFontIndirect( &logFont );\n}\n\n//----------------------------------------------------------------------------\n//\n// EnsureForeground\n//\n//----------------------------------------------------------------------------\nvoid EnsureForeground()\n{\n    if( !IsWindowVisible( g_hWndMain ) )\n        SetForegroundWindow( g_hWndMain );\n}\n\n//----------------------------------------------------------------------------\n//\n// RestoreForeground\n//\n//----------------------------------------------------------------------------\nvoid RestoreForeground()\n{\n    // If the main window is not visible, move foreground to the next window\n    if( !IsWindowVisible( g_hWndMain ) ) {\n\n        // Activate the next window by unhiding and hiding the main window\n        MoveWindow( g_hWndMain, 0, 0, 0, 0, FALSE );\n        ShowWindow( g_hWndMain, SW_SHOWNA );\n        ShowWindow( g_hWndMain, SW_HIDE );\n\n\t\tOutputDebug(L\"RESTORE FOREGROUND\\n\");\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// ErrorDialog\n//\n//----------------------------------------------------------------------------\nVOID ErrorDialog( HWND hParent, PCTSTR message, DWORD _Error )\n{\n    LPTSTR\tlpMsgBuf;\n    TCHAR\terrmsg[1024];\n\n    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,\n                    NULL, _Error, \n                    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n                    reinterpret_cast<LPTSTR>(&lpMsgBuf), 0, NULL );\n    _stprintf( errmsg, L\"%s: %s\", message, lpMsgBuf );\n#ifdef __ZOOMIT_POWERTOYS__\n    if( g_StartedByPowerToys )\n    {\n        Logger::error( errmsg );\n    }\n#endif // __ZOOMIT_POWERTOYS__\n    MessageBox( hParent, errmsg, APPNAME, MB_OK|MB_ICONERROR);\n}\n\n//----------------------------------------------------------------------------\n//\n// ErrorDialogString\n//\n//----------------------------------------------------------------------------\nVOID ErrorDialogString( HWND hParent, PCTSTR Message, const wchar_t *_Error )\n{\n    TCHAR\terrmsg[1024];\n\n    _stprintf_s( errmsg, _countof( errmsg ), L\"%s: %s\", Message, _Error );\n    if( hParent == g_hWndMain )\n    {\n        EnsureForeground();\n    }\n#ifdef __ZOOMIT_POWERTOYS__\n    if( g_StartedByPowerToys )\n    {\n        Logger::error( errmsg );\n    }\n#endif // __ZOOMIT_POWERTOYS__\n    MessageBox(hParent, errmsg, APPNAME, MB_OK | MB_ICONERROR);\n    if( hParent == g_hWndMain )\n    {\n        RestoreForeground();\n    }\n}\n\n\n//--------------------------------------------------------------------\n//\n// SetAutostartFilePath\n//\n// Sets the file path for later autostart config.\n// \n//--------------------------------------------------------------------\nvoid SetAutostartFilePath()\n{\n    HKEY hZoomit;\n    DWORD error;\n    TCHAR imageFile[MAX_PATH] = { 0 };\n\n    error = RegCreateKeyEx( HKEY_CURRENT_USER, _T( \"Software\\\\Sysinternals\\\\Zoomit\" ), 0,\n        0, 0, KEY_SET_VALUE, NULL, &hZoomit, NULL );\n    if( error == ERROR_SUCCESS ) {\n\n        GetModuleFileName( NULL, imageFile + 1, _countof( imageFile ) - 2 );\n        imageFile[0] = '\"';\n        *(_tcschr( imageFile, 0 )) = '\"';\n        error = RegSetValueEx( hZoomit, L\"FilePath\", 0, REG_SZ, (BYTE *) imageFile,\n            static_cast<DWORD>(_tcslen( imageFile ) + 1)* sizeof( TCHAR ));\n        RegCloseKey( hZoomit );\n    }\n}\n\n//--------------------------------------------------------------------\n//\n// ConfigureAutostart\n//\n// Enables or disables Zoomit autostart for the current image file.\n// \n//--------------------------------------------------------------------\nbool ConfigureAutostart( HWND hParent, bool Enable ) \n{\n    HKEY hRunKey, hZoomit;\n    DWORD error, length, type;\n    TCHAR imageFile[MAX_PATH];\n\n    error = RegOpenKeyEx( HKEY_CURRENT_USER, L\"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\", \n        0, KEY_SET_VALUE, &hRunKey );\n    if( error == ERROR_SUCCESS ) {\n\n        if( Enable ) {\n            \n            error = RegOpenKeyEx( HKEY_CURRENT_USER, _T(\"Software\\\\Sysinternals\\\\Zoomit\"), 0, \n                        KEY_QUERY_VALUE, &hZoomit );\n            if( error == ERROR_SUCCESS ) {\n\n                length = sizeof(imageFile);\n#ifdef _WIN64\n                // Unconditionally reset filepath in case this was already set by 32 bit version\n                SetAutostartFilePath();\t\t\n#endif\n                error = RegQueryValueEx( hZoomit, _T( \"Filepath\" ), 0, &type, (BYTE *) imageFile, &length );\n                RegCloseKey( hZoomit );\n                if( error == ERROR_SUCCESS ) {\t\t\n\n                    error = RegSetValueEx( hRunKey, APPNAME, 0, REG_SZ, (BYTE *) imageFile,\n                        static_cast<DWORD>(_tcslen(imageFile)+1) * sizeof(TCHAR));\n                }\n            }\n        } else {\n\n            error = RegDeleteValue( hRunKey, APPNAME );\n            if( error == ERROR_FILE_NOT_FOUND ) error = ERROR_SUCCESS;\n        }\n        RegCloseKey( hRunKey );\n    } \n    if( error != ERROR_SUCCESS ) {\n\n        ErrorDialog( hParent, L\"无法设置开机自启\", error );\n    }\n    return error == ERROR_SUCCESS;\n}\n\n\n//--------------------------------------------------------------------\n//\n// IsAutostartConfigured\n//\n// Is this version of zoomit configured to autostart.\n// \n//--------------------------------------------------------------------\nbool IsAutostartConfigured()\n{\n    HKEY\thRunKey;\n    TCHAR\timageFile[MAX_PATH]; \n    DWORD\terror, imageFileLength, type;\n\n    error = RegOpenKeyEx( HKEY_CURRENT_USER, L\"Software\\\\Microsoft\\\\Windows\\\\CurrentVersion\\\\Run\", \n        0, KEY_QUERY_VALUE, &hRunKey );\n    if( error == ERROR_SUCCESS ) {\n\n        imageFileLength = sizeof(imageFile);\n        error = RegQueryValueEx( hRunKey, _T(\"Zoomit\"), 0, &type, (BYTE *) imageFile, &imageFileLength );\n        RegCloseKey( hRunKey );\n    }\n    return error == ERROR_SUCCESS;\n}\n\n\n#ifndef _WIN64\n\n//--------------------------------------------------------------------\n//\n// RunningOnWin64\n//\n// Returns true if this is the 32-bit version of the executable\n// and we're on 64-bit Windows\n// \n//--------------------------------------------------------------------\ntypedef BOOL (__stdcall *P_IS_WOW64PROCESS)(\n            HANDLE hProcess,\n            PBOOL Wow64Process\n            );\nBOOL \nRunningOnWin64(\n    VOID \n    )\n{\n    P_IS_WOW64PROCESS\t\tpIsWow64Process;\n    BOOL\t\t\t\tisWow64 = FALSE;\n\n    pIsWow64Process = (P_IS_WOW64PROCESS) GetProcAddress(GetModuleHandle(_T(\"kernel32.dll\")),\n                            \"IsWow64Process\");\n    if( pIsWow64Process ) {\n        \n        pIsWow64Process( GetCurrentProcess(), &isWow64 );\n    }\t \n    return isWow64;\n}\n\n\n//--------------------------------------------------------------------\n//\n// ExtractImageResource\n//\n// Extracts the specified file that is located in a resource for \n// this executable.\n//\n//--------------------------------------------------------------------\nBOOLEAN ExtractImageResource( PTCHAR ResourceName, PTCHAR TargetFile )\n{\n    HRSRC\t\thResource;\n    HGLOBAL\t\thImageResource;\n    DWORD\t\tdwImageSize;    \n    LPVOID\t\tlpvImage;\n    FILE\t\t*hFile;\n\n    // Locate the resource\n    hResource = FindResource( NULL, ResourceName, _T(\"BINRES\") ); \n    if( !hResource ) \n        return FALSE;\n    \n    hImageResource\t= LoadResource( NULL, hResource );\n    dwImageSize\t\t= SizeofResource( NULL, hResource );\n    lpvImage\t\t= LockResource( hImageResource );\n\n    // Now copy it out\n    _tfopen_s( &hFile, TargetFile, _T(\"wb\") );\n    if( hFile == NULL ) return FALSE;\n\n    fwrite( lpvImage, 1, dwImageSize, hFile );\n    fclose( hFile );\n    return TRUE;\n}\n\n\n\n//--------------------------------------------------------------------\n//\n// Run64bitVersion\n//\n// Returns true if this is the 32-bit version of the executable\n// and we're on 64-bit Windows\n// \n//--------------------------------------------------------------------\nDWORD \nRun64bitVersion( \n    void\n    )\n{\n    TCHAR\t\tszPath[MAX_PATH];\n    TCHAR\t\toriginalPath[MAX_PATH];\n    TCHAR\t\ttmpPath[MAX_PATH];\n    SHELLEXECUTEINFO\tinfo = { 0 };\n\n    if ( GetModuleFileName( NULL, szPath, sizeof(szPath)/sizeof(TCHAR)) == 0 ) {\n\n        return -1;\n    }\n    _tcscpy_s( originalPath, _countof(originalPath), szPath );\n\n    *_tcsrchr( originalPath, '.') = 0;\n    _tcscat_s( originalPath, _countof(szPath), _T(\"64.exe\"));\n\n    //\n    // Extract the 64-bit version\n    //\n    ExpandEnvironmentStrings( L\"%TEMP%\", tmpPath, sizeof tmpPath / sizeof ( TCHAR));\n    _tcscat_s( tmpPath, _countof(tmpPath), _tcsrchr( originalPath, '\\\\'));\n    _tcscpy_s( szPath, _countof(szPath), tmpPath );\n    if( !ExtractImageResource( _T(\"RCZOOMIT64\"), szPath )) {\n\n        if( GetFileAttributes( szPath ) == INVALID_FILE_ATTRIBUTES ) {\n\n            ErrorDialog( NULL,_T(\"无法启动 64 位版本\"), GetLastError());\n            return -1;\n        }\n    }\n\n    info.cbSize = sizeof(info);\n    info.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS;\n    info.lpFile = szPath;\n    info.lpParameters = GetCommandLine();\n    info.nShow = SW_SHOWNORMAL;\n    if( !ShellExecuteEx( &info ) ) {\n\n        ErrorDialog( NULL,_T(\"无法启动 64 位版本\"), GetLastError());\n        DeleteFile( szPath );\n        return -1;\n    }\n    WaitForSingleObject( info.hProcess, INFINITE );\n\n    DWORD result;\n    GetExitCodeProcess( info.hProcess, &result );\n    CloseHandle( info.hProcess );\n    DeleteFile( szPath );\n    return result;\n}\n#endif\n\n\n//----------------------------------------------------------------------------\n//\n// IsPresentationMode\n//\n//----------------------------------------------------------------------------\nBOOLEAN IsPresentationMode()\n{\n    QUERY_USER_NOTIFICATION_STATE pUserState;\n\n    pSHQueryUserNotificationState( &pUserState );\n    return pUserState == QUNS_PRESENTATION_MODE;\n}\n\n//----------------------------------------------------------------------------\n//\n// EnableDisableSecondaryDisplay\n// \n// Creates a second display on the secondary monitor for displaying the\n// break timer. \n//\n//----------------------------------------------------------------------------\nLONG EnableDisableSecondaryDisplay( HWND hWnd, BOOLEAN Enable, \n                                    PDEVMODE OriginalDevMode ) \n{\n    LONG\t\tresult;\n    DEVMODE\t\tdevMode{};\n\n    if( Enable ) {\n\n        //\n        // Prepare the position of Display 2 to be right to the right of Display 1\n        //\n        devMode.dmSize = sizeof(devMode);\n        devMode.dmDriverExtra = 0;\n        EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode); \n        *OriginalDevMode = devMode;\n\n        //\n        // Enable display 2 in the registry\n        //\n        devMode.dmPosition.x = devMode.dmPelsWidth;\n        devMode.dmFields = DM_POSITION |\n                            DM_DISPLAYORIENTATION |\n                            DM_BITSPERPEL |\n                            DM_PELSWIDTH |\n                            DM_PELSHEIGHT |\n                            DM_DISPLAYFLAGS |\n                            DM_DISPLAYFREQUENCY; \n        result = ChangeDisplaySettingsEx( L\"\\\\\\\\.\\\\DISPLAY2\",\n                                          &devMode,\n                                          NULL,\n                                          CDS_NORESET | CDS_UPDATEREGISTRY,\n                                          NULL);\n\n    } else {\n\n        OriginalDevMode->dmFields = DM_POSITION |\n                            DM_DISPLAYORIENTATION |\n                            DM_BITSPERPEL |\n                            DM_PELSWIDTH |\n                            DM_PELSHEIGHT |\n                            DM_DISPLAYFLAGS |\n                            DM_DISPLAYFREQUENCY;\n        result = ChangeDisplaySettingsEx( L\"\\\\\\\\.\\\\DISPLAY2\",\n                                          OriginalDevMode,\n                                          NULL,\n                                          CDS_NORESET | CDS_UPDATEREGISTRY,\n                                          NULL);\n    }\n\n    //\n    // Update the hardware\n    //\n    if( result == DISP_CHANGE_SUCCESSFUL ) {\n\n        if( !ChangeDisplaySettingsEx(NULL, NULL, NULL, 0, NULL)) {\n\n            result = GetLastError();\n        }\n\n        //\n        // If enabling, move zoomit to the second monitor\n        //\n        if( Enable && result == DISP_CHANGE_SUCCESSFUL ) {\n\n            SetWindowPos(FindWindowW(L\"ZoomitClass\", NULL),\n                     NULL,\n                     devMode.dmPosition.x,\n                     0,\n                     0,\n                     0,\n                     SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE);\n            SetCursorPos( devMode.dmPosition.x+1, devMode.dmPosition.y+1 );\n        }\n    }\n    return result;\n}\n\n//----------------------------------------------------------------------------\n//\n// GetLineBounds\n//\n// Gets the rectangle bounding a line, taking into account pen width\n// \n//----------------------------------------------------------------------------\nGdiplus::Rect GetLineBounds( POINT p1, POINT p2, int penWidth )\n{\n    Gdiplus::Rect rect( min(p1.x, p2.x), min(p1.y, p2.y), \n                        abs(p1.x - p2.x), abs( p1.y - p2.y));\n    rect.Inflate( penWidth, penWidth );\n    return rect;\n}\n\n//----------------------------------------------------------------------------\n//\n// InvalidateGdiplusRect\n//\n// Invalidate portion of window specified by Gdiplus::Rect\n// \n//----------------------------------------------------------------------------\nvoid InvalidateGdiplusRect(HWND hWnd, Gdiplus::Rect BoundsRect)\n{\n    RECT lineBoundsGdi;\n    lineBoundsGdi.left = BoundsRect.X;\n    lineBoundsGdi.top = BoundsRect.Y;\n    lineBoundsGdi.right = BoundsRect.X + BoundsRect.Width;\n    lineBoundsGdi.bottom = BoundsRect.Y + BoundsRect.Height;\n    InvalidateRect(hWnd, &lineBoundsGdi, FALSE);\n}\n\n\n\n//----------------------------------------------------------------------------\n//\n// CreateGdiplusBitmap\n//\n// Creates a gdiplus bitmap of the specified region of the HDC.  \n// \n//----------------------------------------------------------------------------\nGdiplus::Bitmap *CreateGdiplusBitmap( HDC hDc, int x, int y, int Width, int Height )\n{\n    HBITMAP hBitmap = CreateCompatibleBitmap(hDc, Width, Height);\n\n    // Create a device context for the new bitmap\n    HDC hdcNewBitmap = CreateCompatibleDC(hDc);\n    SelectObject(hdcNewBitmap, hBitmap);\n\n    // Copy from the oldest undo bitmap to the new bitmap using the lineBounds as the source rectangle\n    BitBlt(hdcNewBitmap, 0, 0, Width, Height, hDc, x, y, SRCCOPY);\n    Gdiplus::Bitmap *blurBitmap = new Gdiplus::Bitmap(hBitmap, NULL);\n    DeleteDC(hdcNewBitmap);\n    DeleteObject(hBitmap);\n    return blurBitmap; \n}\n\n\n//----------------------------------------------------------------------------\n//\n// CreateBitmapMemoryDIB\n//\n// Creates a memory DC and DIB for the specified region of the screen.\n// \n//----------------------------------------------------------------------------\nBYTE* CreateBitmapMemoryDIB(HDC hdcScreenCompat, HDC hBitmapDc, Gdiplus::Rect* lineBounds,\n    HDC* hdcMem, HBITMAP* hDIBOrig, HBITMAP* hPreviousBitmap)\n{\n    // Create a memory DIB for the relevant region of the original bitmap\n    BITMAPINFO bmiOrig = { 0 };\n    bmiOrig.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n    bmiOrig.bmiHeader.biWidth = lineBounds->Width;\n    bmiOrig.bmiHeader.biHeight = -lineBounds->Height;  // Top-down DIB\n    bmiOrig.bmiHeader.biPlanes = 1;\n    bmiOrig.bmiHeader.biBitCount = 32;  // 32 bits per pixel\n    bmiOrig.bmiHeader.biCompression = BI_RGB;\n\n    VOID* pDIBBitsOrig;\n    *hDIBOrig = CreateDIBSection(hdcScreenCompat, &bmiOrig, DIB_RGB_COLORS, &pDIBBitsOrig, NULL, 0);\n\n    if( *hDIBOrig == NULL ) {\n\n        OutputDebug(L\"NULL DIB: %d\\n\", GetLastError());\n        OutputDebug(L\"lineBounds: %d %d %d %d\\n\", lineBounds->X, lineBounds->Y, lineBounds->Width, lineBounds->Height);\n        return NULL;\n    }\n\n    *hdcMem = CreateCompatibleDC(hdcScreenCompat);\n    *hPreviousBitmap = static_cast<HBITMAP>(SelectObject(*hdcMem, *hDIBOrig));\n\n    // Copy the relevant part of hdcScreenCompat to the DIB\n    BitBlt(*hdcMem, 0, 0, lineBounds->Width, lineBounds->Height, hBitmapDc, lineBounds->X, lineBounds->Y, SRCCOPY);\n\n    // Pointer to the DIB bits\n    return static_cast<BYTE*>(pDIBBitsOrig);\n}\n\n//----------------------------------------------------------------------------\n//\n// LockGdiPlusBitmap\n//\n// Locks the Gdi+ bitmap so that we can access its pixels in memory. \n// \n//----------------------------------------------------------------------------\n#ifdef _MSC_VER\n    // Analyzers want us to use a scoped object instead of new. But given all the operations done in Bitmaps it seems better to leave it as a heap object.\n    #pragma warning(push)\n    #pragma warning(disable : 26402)\n#endif\n\nGdiplus::BitmapData* LockGdiPlusBitmap(Gdiplus::Bitmap* Bitmap)\n{\n    Gdiplus::BitmapData *lineData = new Gdiplus::BitmapData();\n    Bitmap->GetPixelFormat();\n    Gdiplus::Rect lineBitmapBounds(0, 0, Bitmap->GetWidth(), Bitmap->GetHeight());\n    Bitmap->LockBits(&lineBitmapBounds, Gdiplus::ImageLockModeRead,\n        Bitmap->GetPixelFormat(), lineData);\n    return lineData; \n}\n#ifdef _MSC_VER\n    #pragma warning(pop)\n#endif\n\n\n//----------------------------------------------------------------------------\n//\n// BlurScreen\n//\n// Blur the portion of the screen by copying a blurred bitmap with the \n// specified shape. \n// \n//----------------------------------------------------------------------------\nvoid BlurScreen(HDC hdcScreenCompat, Gdiplus::Rect* lineBounds, \n                    Gdiplus::Bitmap *BlurBitmap, BYTE* pPixels)\n{\n    HDC hdcDIB;\n    HBITMAP hDibOrigBitmap, hDibBitmap;\n    BYTE* pDestPixels = CreateBitmapMemoryDIB(hdcScreenCompat, hdcScreenCompat, lineBounds,\n                                &hdcDIB, &hDibBitmap, &hDibOrigBitmap);\n\n    // Iterate through the pixels\n    for (int y = 0; y < lineBounds->Height; ++y) {\n        for (int x = 0; x < lineBounds->Width; ++x) {\n            int index = (y * lineBounds->Width * 4) + (x * 4);  // Assuming 4 bytes per pixel\n            // BYTE b = pPixels[index + 0];  // Blue channel\n            // BYTE g = pPixels[index + 1];  // Green channel\n            // BYTE r = pPixels[index + 2];  // Red channel\n            BYTE a = pPixels[index + 3];  // Alpha channel\n\n            // Check if this is a drawn pixel\n            if (a != 0) {\n                // get the blur pixel\n                Gdiplus::Color pixel;\n                BlurBitmap->GetPixel(x, y, &pixel);\n\n                COLORREF newPixel = pixel.GetValue() & 0xFFFFFF;\n                pDestPixels[index + 0] = GetRValue(newPixel);\n                pDestPixels[index + 1] = GetGValue(newPixel);\n                pDestPixels[index + 2] = GetBValue(newPixel);\n            }\n        }\n    }\n\n    // Copy the updated DIB back to hdcScreenCompat\n    BitBlt(hdcScreenCompat, lineBounds->X, lineBounds->Y, lineBounds->Width, lineBounds->Height, hdcDIB, 0, 0, SRCCOPY);\n\n    // Clean up\n    SelectObject(hdcDIB, hDibOrigBitmap);\n    DeleteObject(hDibBitmap);\n    DeleteDC(hdcDIB);\n}\n\n\n\n//----------------------------------------------------------------------------\n//\n// BitmapBlur\n//\n// Blurs the bitmap. \n// \n//----------------------------------------------------------------------------\nvoid BitmapBlur(Gdiplus::Bitmap* hBitmap)\n{\n    // Git bitmap size\n    Gdiplus::Size bitmapSize;\n    bitmapSize.Width = hBitmap->GetWidth();\n    bitmapSize.Height = hBitmap->GetHeight();\n\n    // Blur the new bitmap\n    Gdiplus::Blur blurObject;\n    Gdiplus::BlurParams blurParams;\n    blurParams.radius = g_BlurRadius;\n    blurParams.expandEdge = FALSE;\n    blurObject.SetParameters(&blurParams);\n\n    // Apply blur to image\n    RECT linesRect;\n    linesRect.left = 0;\n    linesRect.top = 0;\n    linesRect.right = bitmapSize.Width;\n    linesRect.bottom = bitmapSize.Height;\n    hBitmap->ApplyEffect(&blurObject, &linesRect);\n}\n\n\n//----------------------------------------------------------------------------\n//\n// DrawBlurredShape\n//\n// Blur a shaped region of the screen.\n// \n//----------------------------------------------------------------------------\nvoid DrawBlurredShape( DWORD Shape, Gdiplus::Pen *pen, HDC hdcScreenCompat, Gdiplus::Graphics *dstGraphics,\n                    int x1, int y1, int x2, int y2)\n{\n    // Create a new bitmap that's the size of the area covered by the line + 2 * g_PenWidth\n    Gdiplus::Rect lineBounds( min( x1, x2 ), min( y1, y2 ), abs( x2 - x1 ), abs( y2 - y1 ) );\n\n    // Expand for line drawing\n    if (Shape == DRAW_LINE) \n        lineBounds.Inflate( static_cast<int>(g_PenWidth / 2), static_cast<int>(g_PenWidth / 2) );\n\n    Gdiplus::Bitmap* lineBitmap = new Gdiplus::Bitmap(lineBounds.Width, lineBounds.Height, PixelFormat32bppARGB);\n    Gdiplus::Graphics lineGraphics(lineBitmap);\n    static const auto blackBrush = Gdiplus::SolidBrush(Gdiplus::Color::Black);\n    switch (Shape) {\n    case DRAW_RECTANGLE:\n        lineGraphics.FillRectangle(&blackBrush, 0, 0, lineBounds.Width, lineBounds.Height);\n        break;\n    case DRAW_ELLIPSE:\n        lineGraphics.FillEllipse(&blackBrush, 0, 0, lineBounds.Width, lineBounds.Height);\n        break;\n    case DRAW_LINE:\n        OutputDebug(L\"BLUR_LINE: %d %d\\n\", lineBounds.Width, lineBounds.Height);\n        lineGraphics.DrawLine( pen, x1 - lineBounds.X, y1 - lineBounds.Y, x2 - lineBounds.X, y2 - lineBounds.Y );\n        break;\n    }\n\n    Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap);\n    BYTE* pPixels = static_cast<BYTE*>(lineData->Scan0);\n\n    // Create a GDI bitmap that's the size of the lineBounds rectangle\n    Gdiplus::Bitmap* blurBitmap = CreateGdiplusBitmap(hdcScreenCompat,\n        lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height);\n\n    // Blur it\n    BitmapBlur(blurBitmap);\n    BlurScreen(hdcScreenCompat, &lineBounds, blurBitmap, pPixels);\n\n    // Unlock the bits\n    lineBitmap->UnlockBits(lineData);\n    delete lineBitmap;\n    delete blurBitmap;\n}\n\n//----------------------------------------------------------------------------\n//\n// CreateDrawingBitmap\n//\n// Create a bitmap to draw on.\n// \n//----------------------------------------------------------------------------\nGdiplus::Bitmap* CreateDrawingBitmap(Gdiplus::Rect lineBounds )\n{\n    Gdiplus::Bitmap* lineBitmap = new Gdiplus::Bitmap(lineBounds.Width, lineBounds.Height, PixelFormat32bppARGB);\n    Gdiplus::Graphics lineGraphics(lineBitmap);\n    return lineBitmap;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// DrawBitmapLine\n//\n// Creates a bitmap and draws a line on it. \n// \n//----------------------------------------------------------------------------\nGdiplus::Bitmap* DrawBitmapLine(Gdiplus::Rect lineBounds, POINT p1, POINT p2, Gdiplus::Pen *pen)\n{\n    Gdiplus::Bitmap* lineBitmap = new Gdiplus::Bitmap(lineBounds.Width, lineBounds.Height, PixelFormat32bppARGB);\n    Gdiplus::Graphics lineGraphics(lineBitmap);\n\n    // Draw the line on the temporary bitmap\n    lineGraphics.DrawLine(pen, static_cast<INT>(p1.x - lineBounds.X), static_cast<INT>(p1.y - lineBounds.Y),\n        static_cast<INT>(p2.x - lineBounds.X), static_cast<INT>(p2.y - lineBounds.Y));\n\n    return lineBitmap;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// ColorFromColorRef\n//\n// Returns a color object from the colorRef that includes the alpha channel\n// \n//----------------------------------------------------------------------------\nGdiplus::Color ColorFromColorRef(DWORD colorRef) {\n    BYTE a = (colorRef >> 24) & 0xFF;  // Extract the alpha channel value\n    BYTE b = (colorRef >> 16) & 0xFF;  // Extract the red channel value\n    BYTE g = (colorRef >> 8) & 0xFF;   // Extract the green channel value\n    BYTE r = colorRef & 0xFF;          // Extract the blue channel value\n    OutputDebug( L\"ColorFromColorRef: %d %d %d %d\\n\", a, r, g, b );\n    return Gdiplus::Color(a, r, g, b);\n}\n\n//----------------------------------------------------------------------------\n//\n// AdjustHighlighterColor\n//\n// Lighten the color. \n// \n//----------------------------------------------------------------------------\nvoid AdjustHighlighterColor(BYTE* red, BYTE* green, BYTE* blue) {\n\n    // Adjust the color to be more visible\n    *red = min( 0xFF, *red ? *red + 0x40 : *red + 0x80 );\n    *green = min( 0xFF, *green ? *green + 0x40 : *green + 0x80);\n    *blue = min( 0xFF, *blue ? *blue + 0x40 : *blue + 0x80);\n}\n\n//----------------------------------------------------------------------------\n//\n// BlendColors\n//\n// Blends two colors together using the alpha channel of the second color.\n// The highlighter is the second color. \n// \n//----------------------------------------------------------------------------\nCOLORREF BlendColors(COLORREF color1, const Gdiplus::Color& color2) {\n\n    BYTE redResult, greenResult, blueResult;\n\n    // Extract the channels from the COLORREF\n    BYTE red1 = GetRValue(color1);\n    BYTE green1 = GetGValue(color1);\n    BYTE blue1 = GetBValue(color1);\n\n    // Get the channels and alpha from the Gdiplus::Color\n    BYTE blue2 = color2.GetRed();\n    BYTE green2 = color2.GetGreen();\n    BYTE red2 = color2.GetBlue();\n    float alpha2 = color2.GetAlpha() / 255.0f;  // Normalize to [0, 1]\n    //alpha2 /= 2; // Use half the alpha for higher contrast\n\n    // Don't blend grey's as much\n    // int minValue = min(red1, min(green1, blue1));\n    // int maxValue = max(red1, max(green1, blue1));\n    if(TRUE) { // red1 > 0x10 && red1 < 0xC0 && (maxValue - minValue < 0x40)) {\n\n        // This does a standard bright highlight\t\n        alpha2 = 0;\n        AdjustHighlighterColor( &red2, &green2, &blue2 );\n        redResult\t= red2 & red1;\n        greenResult = green2 & green1;\n        blueResult\t= blue2 & blue1;\n    }\n    else {\n\n        // Blend each channel\n        redResult = static_cast<BYTE>(red2 * alpha2 + red1 * (1 - alpha2));\n        greenResult = static_cast<BYTE>(green2 * alpha2 + green1 * (1 - alpha2));\n        blueResult = static_cast<BYTE>(blue2 * alpha2 + blue1 * (1 - alpha2));\n    }\n    // Combine the result channels back into a COLORREF\n    return RGB(redResult, greenResult, blueResult);\n}\n\n\n\n//----------------------------------------------------------------------------\n//\n// DrawHighlightedShape\n//\n// Draws the shape with the highlighter color.\n//\n//----------------------------------------------------------------------------\nvoid DrawHighlightedShape( DWORD Shape, HDC hdcScreenCompat, Gdiplus::Brush *pBrush, \n                        Gdiplus::Pen *pPen, int x1, int y1, int x2, int y2)\n{\n    // Create a new bitmap that's the size of the area covered by the line + 2 * g_PenWidth\n    Gdiplus::Rect lineBounds(min(x1, x2), min(y1, y2), abs(x2 - x1), abs(y2 - y1));\n\n    // Expand for line drawing\n    if (Shape == DRAW_LINE)\n        lineBounds.Inflate(static_cast<int>(g_PenWidth / 2), static_cast<int>(g_PenWidth / 2));\n\n    Gdiplus::Bitmap* lineBitmap = CreateDrawingBitmap(lineBounds);\n    Gdiplus::Graphics lineGraphics(lineBitmap);\n    switch (Shape) {\n    case DRAW_RECTANGLE:\n        lineGraphics.FillRectangle(pBrush, 0, 0, lineBounds.Width, lineBounds.Height);\n        break;\n    case DRAW_ELLIPSE:\n        lineGraphics.FillEllipse( pBrush, 0, 0, lineBounds.Width, lineBounds.Height);\n        break;\t\n    case DRAW_LINE:\n        lineGraphics.DrawLine(pPen, x1 - lineBounds.X, y1 - lineBounds.Y, x2 - lineBounds.X, y2 - lineBounds.Y);\n        break;\n    }\n\n    Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap);\n    BYTE* pPixels = static_cast<BYTE*>(lineData->Scan0);\n\n    // Create a DIB section for efficient pixel manipulation\n    BITMAPINFO bmi = { 0 };\n    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n    bmi.bmiHeader.biWidth = lineBounds.Width;\n    bmi.bmiHeader.biHeight = -lineBounds.Height;  // Top-down DIB\n    bmi.bmiHeader.biPlanes = 1;\n    bmi.bmiHeader.biBitCount = 32;  // 32 bits per pixel\n    bmi.bmiHeader.biCompression = BI_RGB;\n\n    VOID* pDIBBits;\n    HBITMAP hDIB = CreateDIBSection(hdcScreenCompat, &bmi, DIB_RGB_COLORS, &pDIBBits, NULL, 0);\n\n    HDC hdcDIB = CreateCompatibleDC(hdcScreenCompat);\n    SelectObject(hdcDIB, hDIB);\n\n    // Copy the relevant part of hdcScreenCompat to the DIB\n    BitBlt(hdcDIB, 0, 0, lineBounds.Width, lineBounds.Height, hdcScreenCompat, lineBounds.X, lineBounds.Y, SRCCOPY);\n\n    // Pointer to the DIB bits\n    BYTE* pDestPixels = static_cast<BYTE*>(pDIBBits);\n\n    // Pointer to screen bits\n    HDC hdcDIBOrig;\n    HBITMAP hDibOrigBitmap, hDibBitmap;\n    BYTE* pDestPixels2 = CreateBitmapMemoryDIB(hdcScreenCompat, hdcScreenCompat, &lineBounds,\n        &hdcDIBOrig, &hDibBitmap, &hDibOrigBitmap);\n\n    for (int y = 0; y < lineBounds.Height; ++y) {\n        for (int x = 0; x < lineBounds.Width; ++x) {\n            int index = (y * lineBounds.Width * 4) + (x * 4);  // Assuming 4 bytes per pixel\n            // BYTE b = pPixels[index + 0];  // Blue channel\n            // BYTE g = pPixels[index + 1];  // Green channel\n            // BYTE r = pPixels[index + 2];  // Red channel\n            BYTE a = pPixels[index + 3];  // Alpha channel\n\n            // Check if this is a drawn pixel\n            if (a != 0) {\n                // Assuming pDestPixels is a valid pointer to the destination bitmap's pixel data\n                BYTE destB = pDestPixels2[index + 0];  // Blue channel\n                BYTE destG = pDestPixels2[index + 1];  // Green channel\n                BYTE destR = pDestPixels2[index + 2];  // Red channel\n\n                // Create a COLORREF value from the destination pixel data\n                COLORREF currentPixel = RGB(destR, destG, destB);\n                // Blend the colors\n                COLORREF newPixel = BlendColors(currentPixel, g_PenColor);\n                // Update the destination pixel data with the new color\n                pDestPixels[index + 0] = GetBValue(newPixel);\n                pDestPixels[index + 1] = GetGValue(newPixel);\n                pDestPixels[index + 2] = GetRValue(newPixel);\n            }\n        }\n    }\n\n    // Copy the updated DIB back to hdcScreenCompat\n    BitBlt(hdcScreenCompat, lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height, hdcDIB, 0, 0, SRCCOPY);\n\n    // Clean up\n    DeleteObject(hDIB);\n    DeleteDC(hdcDIB);\n\n    SelectObject(hdcDIBOrig, hDibOrigBitmap);\n    DeleteObject(hDibBitmap);\n    DeleteDC(hdcDIBOrig);\n\n    // Invalidate the updated rectangle\n    // InvalidateGdiplusRect(hWnd, lineBounds);\n}\n\n//----------------------------------------------------------------------------\n//\n// CreateFadedDesktopBackground\n//\n// Creates a snapshot of the desktop that's faded and alpha blended with \n// black.\n//\n//----------------------------------------------------------------------------\nHBITMAP CreateFadedDesktopBackground( HDC hdc, LPRECT rcScreen, LPRECT rcCrop )\n{\n    // create bitmap\n    int\t\twidth\t\t= rcScreen->right - rcScreen->left;\n    int\t\theight\t\t= rcScreen->bottom - rcScreen->top;\n    HDC\t\thdcScreen\t= hdc;\n    HDC\t\thdcMem\t\t= CreateCompatibleDC( hdcScreen );\n    HBITMAP\thBitmap\t\t= CreateCompatibleBitmap( hdcScreen, width, height );\n    HBITMAP\thOld\t\t= static_cast<HBITMAP>(SelectObject( hdcMem, hBitmap ));\n    HBRUSH\thBrush\t\t= CreateSolidBrush(RGB(0, 0, 0));\n    \n    // start with black background\n    FillRect( hdcMem, rcScreen, hBrush );\n    if(rcCrop != NULL && rcCrop->left != -1 ) {\n\n        // copy screen contents that are not cropped\n        BitBlt(hdcMem, rcCrop->left, rcCrop->top, rcCrop->right - rcCrop->left,\n            rcCrop->bottom - rcCrop->top, hdcScreen, rcCrop->left, rcCrop->top, SRCCOPY);\n    }\n\n    // blend screen contents into it\n    BLENDFUNCTION\tblend = { 0 };\n    blend.BlendOp\t\t\t\t= AC_SRC_OVER;\n    blend.BlendFlags\t\t\t= 0;\n    blend.SourceConstantAlpha   = 0x4F;\n    blend.AlphaFormat\t\t\t= 0;\n    AlphaBlend( hdcMem,0, 0, width, height, \n                hdcScreen, rcScreen->left, rcScreen->top, \n                width, height, blend );\n\n    SelectObject( hdcMem, hOld );\n    DeleteDC( hdcMem );\n    DeleteObject(hBrush);\n    ReleaseDC( NULL, hdcScreen );\n\n    return hBitmap;\n}\n\n//----------------------------------------------------------------------------\n//\n// AdjustToMoveBoundary\n//\n// Shifts to accomodate move boundary.\n//\n//----------------------------------------------------------------------------\nvoid AdjustToMoveBoundary( float zoomLevel, int *coordinate, int cursor, int size, int max )\n{\n    int diff = static_cast<int> (static_cast<float>(size)/ static_cast<float>(LIVEZOOM_MOVE_REGIONS));\n    if( cursor - *coordinate < diff ) \n        *coordinate = max( 0, cursor - diff ); \n    else if( (*coordinate + size) - cursor < diff ) \n        *coordinate = min( cursor + diff - size, max - size );\n}\n\n//----------------------------------------------------------------------------\n//\n// GetZoomedTopLeftCoordinates\n//\n// Gets the left top coordinate of the zoomed area of the screen\n//\n//----------------------------------------------------------------------------\nvoid GetZoomedTopLeftCoordinates( float zoomLevel, POINT *cursorPos, int *x, int width, int *y, int height )\n{\n    // smoother and more natural zoom in\n    float scaledWidth = width/zoomLevel;\n    float scaledHeight = height/zoomLevel;\n    *x = max( 0, min( (int) (width - scaledWidth), (int) (cursorPos->x - (int) (((float) cursorPos->x/ (float) width)*scaledWidth))));\n    AdjustToMoveBoundary( zoomLevel, x, cursorPos->x, static_cast<int>(scaledWidth), width );\n    *y = max( 0, min( (int) (height - scaledHeight), (int) (cursorPos->y - (int) (((float) cursorPos->y/ (float) height)*scaledHeight))));\n    AdjustToMoveBoundary( zoomLevel, y, cursorPos->y, static_cast<int>(scaledHeight), height );\n}\n\n\n//----------------------------------------------------------------------------\n//\n// ScaleImage\n//\n// Use gdi+ for anti-aliased bitmap stretching. \n//\n//----------------------------------------------------------------------------\nvoid ScaleImage( HDC hdcDst, float xDst, float yDst, float wDst, float hDst, \n                 HBITMAP bmSrc, float xSrc, float ySrc, float wSrc, float hSrc )\n{\n    Gdiplus::Graphics\tdstGraphics( hdcDst );\n    {\n        Gdiplus::Bitmap\t\tsrcBitmap( bmSrc, NULL );\n\n        dstGraphics.SetInterpolationMode( Gdiplus::InterpolationModeLowQuality );\n        dstGraphics.SetPixelOffsetMode( Gdiplus::PixelOffsetModeHalf );\n\n        dstGraphics.DrawImage( &srcBitmap, Gdiplus::RectF(xDst,yDst,wDst,hDst), xSrc, ySrc, wSrc, hSrc, Gdiplus::UnitPixel );\n    }\n}\n\n\n//----------------------------------------------------------------------------\n//\n// GetEncoderClsid\n//\n//----------------------------------------------------------------------------\nint GetEncoderClsid(const WCHAR* format, CLSID* pClsid)\n{\n   UINT  num = 0;          // number of image encoders\n   UINT  size = 0;         // size of the image encoder array in bytes\nusing namespace Gdiplus;\n\n   ImageCodecInfo* pImageCodecInfo = NULL;\n\n   GetImageEncodersSize(&num, &size);\n   if(size == 0)\n      return -1;  // Failure\n\n   pImageCodecInfo = static_cast<ImageCodecInfo*>(malloc(size));\n   if(pImageCodecInfo == NULL)\n      return -1;  // Failure\n\n   GetImageEncoders(num, size, pImageCodecInfo);\n\n   for(UINT j = 0; j < num; ++j)\n   {\n      if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )\n      {\n         *pClsid = pImageCodecInfo[j].Clsid;\n         free(pImageCodecInfo);\n         return j;  // Success\n      }    \n   }\n\n   free(pImageCodecInfo);\n   return -1;  // Failure\n}\n\n//----------------------------------------------------------------------\n//  \n// ConvertToUnicode\n//\n//----------------------------------------------------------------------\nvoid \nConvertToUnicode( \n    PCHAR aString, \n    PWCHAR  wString, \n    DWORD wStringLength \n    )\n{\n    size_t\tlen;\n\n    len = MultiByteToWideChar( CP_ACP, 0, aString, static_cast<int>(strlen(aString)), \n                wString, wStringLength );\n    wString[len] = 0;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// LoadImageFile\n//\n// Use gdi+ to load an image.\n//\n//----------------------------------------------------------------------------\nHBITMAP LoadImageFile( PTCHAR Filename )\n{\n    HBITMAP\t\thBmp;\n\n    Gdiplus::Bitmap\t\t*bitmap;\n\n    bitmap = Gdiplus::Bitmap::FromFile(Filename);\n    if( bitmap->GetHBITMAP( NULL, &hBmp )) {\n\n        return NULL;\n    }\n    delete bitmap;\n    return hBmp;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// SavePng\n//\n// Use gdi+ to save a PNG.\n//\n//----------------------------------------------------------------------------\nDWORD SavePng( PTCHAR Filename, HBITMAP hBitmap )\n{\n    Gdiplus::Bitmap\t\tbitmap( hBitmap, NULL );\n    CLSID pngClsid;\n    GetEncoderClsid(L\"image/png\", &pngClsid);\n    if( bitmap.Save( Filename, &pngClsid, NULL )) {\n\n        return GetLastError();\n    }\n    return ERROR_SUCCESS;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// EnableDisableTrayIcon\n//\n//----------------------------------------------------------------------------\nvoid EnableDisableTrayIcon( HWND hWnd, BOOLEAN Enable )\n{\n    NOTIFYICONDATA tNotifyIconData;\n\n    memset( &tNotifyIconData, 0, sizeof(tNotifyIconData));\n    tNotifyIconData.cbSize = sizeof(NOTIFYICONDATA); \n    tNotifyIconData.hWnd = hWnd; \n    tNotifyIconData.uID = 1; \n    tNotifyIconData.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; \n    tNotifyIconData.uCallbackMessage = WM_USER_TRAY_ACTIVATE; \n    tNotifyIconData.hIcon = LoadIcon( g_hInstance, L\"APPICON\" ); \n    lstrcpyn(tNotifyIconData.szTip, APPNAME, sizeof(APPNAME));\n    Shell_NotifyIcon(Enable ? NIM_ADD : NIM_DELETE, &tNotifyIconData); \n}\n\n//----------------------------------------------------------------------------\n//\n// EnableDisableOpacity\n//\n//----------------------------------------------------------------------------\nvoid EnableDisableOpacity( HWND hWnd, BOOLEAN Enable ) \n{\n    DWORD\texStyle;\n\n    if( pSetLayeredWindowAttributes && g_BreakOpacity != 100 ) {\n\n        if( Enable ) {\n\n            exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);\n            SetWindowLong(hWnd, GWL_EXSTYLE, (exStyle | WS_EX_LAYERED));\n\n            pSetLayeredWindowAttributes(hWnd, 0, static_cast<BYTE> ((255 * g_BreakOpacity) / 100), LWA_ALPHA);\n            RedrawWindow(hWnd, 0, 0, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);\n\n        } else {\n\n            exStyle = GetWindowLong(hWnd, GWL_EXSTYLE);\n            SetWindowLong(hWnd, GWL_EXSTYLE, (exStyle & ~WS_EX_LAYERED));\n        }\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// EnableDisableScreenSaver\n//\n//----------------------------------------------------------------------------\nvoid EnableDisableScreenSaver( BOOLEAN Enable ) \n{\n    SystemParametersInfo(SPI_SETSCREENSAVEACTIVE,Enable,0,0); \n    SystemParametersInfo(SPI_SETPOWEROFFACTIVE,Enable,0,0); \n    SystemParametersInfo(SPI_SETLOWPOWERACTIVE,Enable,0,0); \n}\n\n//----------------------------------------------------------------------------\n//\n// EnableDisableStickyKeys\n//\n//----------------------------------------------------------------------------\nvoid EnableDisableStickyKeys( BOOLEAN Enable )\n{\n    static STICKYKEYS\tprevStickyKeyValue = {0};\n    STICKYKEYS\t\t\tnewStickyKeyValue = {0};\n\n    // Need to do this on Vista tablet to stop sticky key popup when you \n    // hold down the shift key and draw with the pen.\n    if( Enable ) {\n\n        if( prevStickyKeyValue.cbSize == sizeof(STICKYKEYS)) {\n\n            SystemParametersInfo(SPI_SETSTICKYKEYS, \n                    sizeof(STICKYKEYS), &prevStickyKeyValue, SPIF_SENDCHANGE);\n        }\n\n    } else {\n\n        prevStickyKeyValue.cbSize = sizeof(STICKYKEYS);\n        if (SystemParametersInfo(SPI_GETSTICKYKEYS, sizeof(STICKYKEYS), \n                &prevStickyKeyValue, 0)) {\n\n            newStickyKeyValue.cbSize = sizeof(STICKYKEYS);\n            newStickyKeyValue.dwFlags = 0;\n            if( !SystemParametersInfo(SPI_SETSTICKYKEYS, \n                sizeof(STICKYKEYS), &newStickyKeyValue, SPIF_SENDCHANGE)) {\n\n                // DWORD error = GetLastError();\n\n            }\n        }\n    }\n}\n\n\n//----------------------------------------------------------------------------\n//\n// GetKeyMod\n//\n//----------------------------------------------------------------------------\nconstexpr DWORD GetKeyMod( DWORD Key )\n{\n    DWORD\t keyMod = 0;\n    if( (Key >> 8) & HOTKEYF_ALT ) keyMod |= MOD_ALT;\n    if( (Key >> 8) & HOTKEYF_CONTROL) keyMod |= MOD_CONTROL;\n    if( (Key >> 8) & HOTKEYF_SHIFT) keyMod |= MOD_SHIFT;\n    if( (Key >> 8) & HOTKEYF_EXT) keyMod |= MOD_WIN;\n    return keyMod;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// AdvancedBreakProc\n//\n//----------------------------------------------------------------------------\nINT_PTR CALLBACK AdvancedBreakProc( HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam ) \n{\n    TCHAR\topacity[10];\n    static\tTCHAR newSoundFile[MAX_PATH];\n    static\tTCHAR newBackgroundFile[MAX_PATH];\n    TCHAR\tfilePath[MAX_PATH], initDir[MAX_PATH];\n    DWORD\ti;\n    OPENFILENAME\topenFileName;\n\n    switch ( message )  {\n    case WM_INITDIALOG:\n        if( pSHAutoComplete ) {\n            pSHAutoComplete( GetDlgItem( hDlg, IDC_SOUND_FILE), SHACF_FILESYSTEM );\n            pSHAutoComplete( GetDlgItem( hDlg, IDC_BACKGROUND_FILE), SHACF_FILESYSTEM );\n        }\n        CheckDlgButton( hDlg, IDC_CHECK_BACKGROUND_FILE, \n            g_BreakShowBackgroundFile ? BST_CHECKED: BST_UNCHECKED );\n        CheckDlgButton( hDlg, IDC_CHECK_SOUND_FILE, \n            g_BreakPlaySoundFile ? BST_CHECKED: BST_UNCHECKED );\n        CheckDlgButton( hDlg, IDC_CHECK_SHOW_EXPIRED,\n            g_ShowExpiredTime ? BST_CHECKED : BST_UNCHECKED );\n        CheckDlgButton( hDlg, IDC_CHECK_BACKGROUND_STRETCH,\n            g_BreakBackgroundStretch ? BST_CHECKED : BST_UNCHECKED );\n#if 0\n        CheckDlgButton( hDlg, IDC_CHECK_SECONDARYDISPLAY,\n            g_BreakOnSecondary ? BST_CHECKED : BST_UNCHECKED );\n#endif\n        if( pSetLayeredWindowAttributes == NULL ) {\n\n            EnableWindow( GetDlgItem( hDlg, IDC_OPACITY ), FALSE );\n        }\n\n        // sound file\n        if( !g_BreakPlaySoundFile ) {\n\n            EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SOUND_FILE ), FALSE );\n            EnableWindow( GetDlgItem( hDlg, IDC_SOUND_FILE ), FALSE );\n            EnableWindow( GetDlgItem( hDlg, IDC_SOUND_BROWSE ), FALSE );\n        }\n        _tcscpy( newSoundFile, g_BreakSoundFile );\n        _tcscpy( filePath, g_BreakSoundFile );\n        if( _tcsrchr( filePath, '\\\\' )) _tcscpy( filePath, _tcsrchr( g_BreakSoundFile, '\\\\' )+1);\n        if( _tcsrchr( filePath, '.' )) *_tcsrchr( filePath, '.' ) = 0;\n        SetDlgItemText( hDlg, IDC_SOUND_FILE, filePath );\n\n        // background file\n        if( !g_BreakShowBackgroundFile ) {\n\n            EnableWindow( GetDlgItem( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ), FALSE );\n            EnableWindow( GetDlgItem( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ), FALSE );\n            EnableWindow( GetDlgItem( hDlg, IDC_STATIC_BACKGROUND_FILE ), FALSE );\n            EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_FILE ), FALSE );\n            EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_BROWSE ), FALSE );\n            EnableWindow( GetDlgItem( hDlg, IDC_CHECK_BACKGROUND_STRETCH ), FALSE );\n        }\n        CheckDlgButton( hDlg, \n            g_BreakShowDesktop ? IDC_STATIC_DESKTOP_BACKGROUND : IDC_STATIC_BACKGROUND_FILE, BST_CHECKED );\n        _tcscpy( newBackgroundFile, g_BreakBackgroundFile );\n        SetDlgItemText( hDlg, IDC_BACKGROUND_FILE, g_BreakBackgroundFile );\n\n        CheckDlgButton( hDlg, IDC_TIMER_POS1 + g_BreakTimerPosition, BST_CHECKED );\n\n        for( i = 10; i <= 100; i += 10) {\n\n            _stprintf( opacity, L\"%d%%\", i );\n            SendMessage( GetDlgItem( hDlg, IDC_OPACITY ), CB_ADDSTRING, 0, \n                    reinterpret_cast<LPARAM>(opacity));\n        }\n        SendMessage( GetDlgItem( hDlg, IDC_OPACITY ), CB_SETCURSEL, \n                g_BreakOpacity / 10 - 1, 0 );\n        return TRUE;\n\n    case WM_COMMAND:\n        switch ( HIWORD( wParam )) {\n        case BN_CLICKED:\n            if( LOWORD( wParam ) == IDC_CHECK_SOUND_FILE ) {\n\n                EnableWindow( GetDlgItem( hDlg, IDC_STATIC_SOUND_FILE ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE) == BST_CHECKED );\n                EnableWindow( GetDlgItem( hDlg, IDC_SOUND_FILE ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE) == BST_CHECKED );\n                EnableWindow( GetDlgItem( hDlg, IDC_SOUND_BROWSE ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE) == BST_CHECKED );\t\t\t\t\n            }\n            if( LOWORD( wParam ) == IDC_CHECK_BACKGROUND_FILE ) {\n\n                EnableWindow( GetDlgItem( hDlg, IDC_CHECK_BACKGROUND_STRETCH ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED );\n                EnableWindow( GetDlgItem( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED );\n                EnableWindow( GetDlgItem( hDlg, IDC_STATIC_BACKGROUND_FILE ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED );\n                EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_FILE ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED );\n                EnableWindow( GetDlgItem( hDlg, IDC_BACKGROUND_BROWSE ), \n                        IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE) == BST_CHECKED );\t\t\t\t\n            }\n            break;\n        }\n        switch ( LOWORD( wParam )) {\n        case IDC_SOUND_BROWSE:\n            memset( &openFileName, 0, sizeof(openFileName ));\n            openFileName.lStructSize       = OPENFILENAME_SIZE_VERSION_400;\n            openFileName.hwndOwner         = hDlg;\n            openFileName.hInstance         = static_cast<HINSTANCE>(g_hInstance);\n            openFileName.nMaxFile          = sizeof(filePath)/sizeof(filePath[0]);\n            openFileName.Flags\t\t\t\t= OFN_LONGNAMES;\n            openFileName.lpstrTitle        = L\"请选择音频文件...\";\n            openFileName.lpstrDefExt       = L\"*.wav\";\n            openFileName.nFilterIndex      = 1;\n            openFileName.lpstrFilter       = L\"WAV 音频\\0*.wav\\0所有文件\\0*.*\\0\";\n\n            GetDlgItemText( hDlg, IDC_SOUND_FILE, filePath, sizeof(filePath ));\n            if( _tcsrchr( filePath, '\\\\' )) {\n\n                _tcscpy( initDir, filePath );\n                _tcscpy( filePath, _tcsrchr( initDir, '\\\\' )+1);\n                *(_tcsrchr( initDir, '\\\\' )+1) = 0;\n            } else {\n\n                _tcscpy( filePath, L\"%WINDIR%\\\\Media\" );\n                ExpandEnvironmentStrings( filePath, initDir, sizeof(initDir)/sizeof(initDir[0]));\n                GetDlgItemText( hDlg, IDC_SOUND_FILE, filePath, sizeof(filePath ));\n            }\n            openFileName.lpstrInitialDir = initDir;\n            openFileName.lpstrFile = filePath;\n            if( GetOpenFileName( &openFileName )) {\n\n                _tcscpy( newSoundFile, filePath );\n                if(_tcsrchr( filePath, '\\\\' )) _tcscpy( filePath, _tcsrchr( newSoundFile, '\\\\' )+1);\n                if(_tcsrchr( filePath, '.' )) *_tcsrchr( filePath, '.' ) = 0;\n                SetDlgItemText( hDlg, IDC_SOUND_FILE, filePath );\n            }\n            break;\n\n        case IDC_BACKGROUND_BROWSE:\n            memset( &openFileName, 0, sizeof(openFileName ));\n            openFileName.lStructSize       = OPENFILENAME_SIZE_VERSION_400;\n            openFileName.hwndOwner         = hDlg;\n            openFileName.hInstance         = static_cast<HINSTANCE>(g_hInstance);\n            openFileName.nMaxFile          = sizeof(filePath)/sizeof(filePath[0]);\n            openFileName.Flags\t\t\t\t= OFN_LONGNAMES;\n            openFileName.lpstrTitle        = L\"请选择背景图片文件...\";\n            openFileName.lpstrDefExt       = L\"*.bmp\";\n            openFileName.nFilterIndex      = 5;\n            openFileName.lpstrFilter       = L\"位图文件 (*.bmp;*.dib)\\0*.bmp;*.dib\\0\"\n                                             \"PNG 文件 (*.png)\\0*.png\\0\"\n                                             \"JPEG 文件 (*.jpg;*.jpeg;*.jpe;*.jfif)\\0*.jpg;*.jpeg;*.jpe;*.jfif\\0\"\n                                             \"GIF 文件 (*.gif)\\0*.gif\\0\"\n                                             \"所有图像文件\\0.bmp;*.dib;*.png;*.jpg;*.jpeg;*.jpe;*.jfif;*.gif)\\0\"\n                                             \"所有文件\\0*.*\\0\\0\";\n\n            GetDlgItemText( hDlg, IDC_BACKGROUND_FILE, filePath, sizeof(filePath ));\n            if(_tcsrchr( filePath, '\\\\' )) {\n\n                _tcscpy( initDir, filePath );\n                _tcscpy( filePath, _tcsrchr( initDir, '\\\\' )+1);\n                *(_tcsrchr( initDir, '\\\\' )+1) = 0;\n            } else {\n\n                _tcscpy( filePath, L\"%USERPROFILE%\\\\Pictures\" );\n                ExpandEnvironmentStrings( filePath, initDir, sizeof(initDir)/sizeof(initDir[0]));\n                GetDlgItemText( hDlg, IDC_BACKGROUND_FILE, filePath, sizeof(filePath ));\n            }\n            openFileName.lpstrInitialDir = initDir;\n            openFileName.lpstrFile = filePath;\n            if( GetOpenFileName( &openFileName )) {\n\n                _tcscpy( newBackgroundFile, filePath );\n                SetDlgItemText( hDlg, IDC_BACKGROUND_FILE, filePath );\n            }\n            break;\n\n        case IDOK:\n\n            // sound file has to be valid\n            g_BreakPlaySoundFile = IsDlgButtonChecked( hDlg, IDC_CHECK_SOUND_FILE ) == BST_CHECKED;\n            g_BreakShowBackgroundFile = IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_FILE ) == BST_CHECKED;\n            g_BreakBackgroundStretch = IsDlgButtonChecked( hDlg, IDC_CHECK_BACKGROUND_STRETCH ) == BST_CHECKED;\n#if 0\n            g_BreakOnSecondary = IsDlgButtonChecked( hDlg, IDC_CHECK_SECONDARYDISPLAY ) == BST_CHECKED;\n#endif\n            if( g_BreakPlaySoundFile && GetFileAttributes( newSoundFile ) == -1 ) {\n\n                MessageBox( hDlg, L\"无法访问所选的音频文件\", \n                        L\"倒计时高级选项错误\", MB_ICONERROR );\n                break;\n            }\n            _tcscpy( g_BreakSoundFile, newSoundFile );\n\n            // Background file\n            g_BreakShowDesktop = IsDlgButtonChecked( hDlg, IDC_STATIC_DESKTOP_BACKGROUND ) == BST_CHECKED;\n\n            if( !g_BreakShowDesktop && g_BreakShowBackgroundFile && GetFileAttributes( newBackgroundFile ) == -1 ) {\n\n                MessageBox( hDlg, L\"无法访问所选的背景图像文件\", \n                        L\"倒计时高级选项错误\", MB_ICONERROR );\n                break;\n            }\n            _tcscpy( g_BreakBackgroundFile, newBackgroundFile );\n\n            for( i = 0; i < 10; i++ ) {\n\n                if( IsDlgButtonChecked( hDlg, IDC_TIMER_POS1+i) == BST_CHECKED ) {\n\n                    g_BreakTimerPosition = i;\n                    break;\n                }\n            }\n            GetDlgItemText( hDlg, IDC_OPACITY, opacity, sizeof(opacity)/sizeof(opacity[0])); \n            _stscanf( opacity, L\"%d%%\", &g_BreakOpacity );\n            reg.WriteRegSettings( RegSettings );\n            EndDialog(hDlg, 0);\n            break;\n\n        case IDCANCEL:\n            EndDialog( hDlg, 0 );\n            return TRUE;\n        }\n        break;\n\n    default:\n        break;\n    }\n    return FALSE;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// OptionsTabProc\n//\n//----------------------------------------------------------------------------\nINT_PTR CALLBACK OptionsTabProc( HWND hDlg, UINT message, \n                                WPARAM wParam, LPARAM lParam ) \n{\n    HDC\t\t\thDC;\n    LOGFONT\t\tlf;\n    CHOOSEFONT\tchooseFont;\n    HFONT\t\thFont;\n    PAINTSTRUCT\tps; \n    HWND\t\thTextPreview;\n    HDC\t\t\thDc;\n    RECT\t\tpreviewRc;\n    TCHAR\t    filePath[MAX_PATH] = {0};\n    OPENFILENAME\topenFileName;\n\n    switch ( message )  {\n    case WM_INITDIALOG:\n        return TRUE;\n    case WM_COMMAND:\n        switch ( LOWORD( wParam )) {\n        case IDC_ADVANCED_BREAK:\n            DialogBox( g_hInstance, L\"ADVANCED_BREAK\", hDlg, AdvancedBreakProc );\n            break;\n        case IDC_FONT:\n            hDC = GetDC (hDlg );\n            lf = g_LogFont;\n            lf.lfHeight = -21;\n            chooseFont.hDC = CreateCompatibleDC (hDC);\n            ReleaseDC (hDlg, hDC);\n            chooseFont.lStructSize = sizeof (CHOOSEFONT);\n            chooseFont.hwndOwner = hDlg;\n            chooseFont.lpLogFont = &lf;\n            chooseFont.Flags     = CF_SCREENFONTS|CF_ENABLETEMPLATE|\n                        CF_INITTOLOGFONTSTRUCT|CF_LIMITSIZE; \n            chooseFont.rgbColors = RGB (0, 0, 0);\n            chooseFont.lCustData = 0;\n            chooseFont.nSizeMin  = 16;\n            chooseFont.nSizeMax  = 16;\n            chooseFont.hInstance = g_hInstance;\n            chooseFont.lpszStyle = static_cast<LPTSTR>(NULL);\n            chooseFont.nFontType = SCREEN_FONTTYPE;\n            chooseFont.lpfnHook  = reinterpret_cast<LPCFHOOKPROC>(static_cast<FARPROC>(NULL));\n            chooseFont.lpTemplateName = static_cast<LPTSTR>(MAKEINTRESOURCE (FORMATDLGORD31));\n            if( ChooseFont( &chooseFont ) ) {\n                g_LogFont = lf;\n                InvalidateRect( hDlg, NULL, TRUE );\n            }\n            break;\n        case IDC_DEMOTYPE_BROWSE:\n            memset( &openFileName, 0, sizeof( openFileName ) );\n            openFileName.lStructSize  = OPENFILENAME_SIZE_VERSION_400;\n            openFileName.hwndOwner    = hDlg;\n            openFileName.hInstance    = static_cast<HINSTANCE>(g_hInstance);\n            openFileName.nMaxFile     = sizeof( filePath ) / sizeof( filePath[0] );\n            openFileName.Flags        = OFN_LONGNAMES;\n            openFileName.lpstrTitle   = L\"请选择自动打字文件...\";\n            openFileName.nFilterIndex = 1;\n            openFileName.lpstrFilter  = L\"所有文件\\0*.*\\0\\0\";\n            openFileName.lpstrFile    = filePath;\n            \n            if( GetOpenFileName( &openFileName ) )\n            {\n                if( GetFileAttributes( filePath ) == -1 )\n                {\n                    MessageBox( hDlg, L\"无法访问所选文件\", APPNAME, MB_ICONERROR );\n                }\n                else\n                {\n                    SetDlgItemText( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_FILE, filePath );\n                    _tcscpy( g_DemoTypeFile, filePath );\n                }\n            }\n            break;\n        }\n        break;\n\n    case WM_PAINT:\n        if( (hTextPreview = GetDlgItem( hDlg, IDC_TEXT_FONT ))) {\n\n            // 16-pt preview\n            LOGFONT _lf = g_LogFont;\n            _lf.lfHeight = -21;\n            hFont = CreateFontIndirect( &_lf);\n            hDc = BeginPaint(hDlg, &ps); \n            SelectObject( hDc, hFont );\n\n            GetWindowRect( hTextPreview, &previewRc );\n            MapWindowPoints( NULL, hDlg, reinterpret_cast<LPPOINT>(&previewRc), 2); \n\n            previewRc.top += 6;\n            DrawText( hDc, L\"Sample\", static_cast<int>(_tcslen(L\"Sample\")), &previewRc, \n                DT_CENTER|DT_VCENTER|DT_SINGLELINE );\n\n            EndPaint( hDlg, &ps );\n            DeleteObject( hFont );\n        }\n        break;\t\n    default:\n        break;\n    }\n    return FALSE;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// OptionsAddTabs\n//\n//----------------------------------------------------------------------------\nVOID OptionsAddTabs( HWND hOptionsDlg, HWND hTabCtrl ) \n{\n    int\t\ti;\n    TCITEM\ttcItem;\n    RECT\trc, pageRc;\n\n    GetWindowRect( hTabCtrl, &rc );\n    for( i = 0; i < sizeof( g_OptionsTabs )/sizeof(g_OptionsTabs[0]); i++ ) {\n\n        TCHAR* displayName = g_OptionsTabs[i].TabTitle;\n        if (_tcscmp(displayName, _T(\"Zoom\")) == 0) displayName = _T(\"放大\");\n        else if (_tcscmp(displayName, _T(\"LiveZoom\")) == 0) displayName = _T(\"实时放大\");\n        else if (_tcscmp(displayName, _T(\"Draw\")) == 0) displayName = _T(\"画图\");\n        else if (_tcscmp(displayName, _T(\"Type\")) == 0) displayName = _T(\"文本\");\n        else if (_tcscmp(displayName, _T(\"DemoType\")) == 0) displayName = _T(\"自动打字\");\n        else if (_tcscmp(displayName, _T(\"Break\")) == 0) displayName = _T(\"倒计时\");\n        else if (_tcscmp(displayName, _T(\"Record\")) == 0) displayName = _T(\"录屏\");\n        else if (_tcscmp(displayName, _T(\"Snip\")) == 0) displayName = _T(\"截图\");\n        tcItem.mask = TCIF_TEXT;\n        tcItem.pszText = displayName;\n        TabCtrl_InsertItem( hTabCtrl, i, &tcItem );\n        g_OptionsTabs[i].hPage = CreateDialog( g_hInstance, g_OptionsTabs[i].TabTitle, \n                    hOptionsDlg, OptionsTabProc );\n    }\n    TabCtrl_AdjustRect( hTabCtrl, FALSE, &rc );\n    for( i = 0; i < sizeof( g_OptionsTabs )/sizeof(g_OptionsTabs[0]); i++ ) {\n\n        pageRc = rc;\n        MapWindowPoints( NULL, g_OptionsTabs[i].hPage, reinterpret_cast<LPPOINT>(&pageRc), 2); \n\n        SetWindowPos( g_OptionsTabs[i].hPage,\n             HWND_TOP,\n             pageRc.left, pageRc.top,\n             pageRc.right - pageRc.left, pageRc.bottom - pageRc.top,\n             SWP_NOACTIVATE|(i == 0 ? SWP_SHOWWINDOW : SWP_HIDEWINDOW));\n\n        if( pEnableThemeDialogTexture ) {\n\n            pEnableThemeDialogTexture( g_OptionsTabs[i].hPage, ETDT_ENABLETAB );\n        }\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// UnregisterAllHotkeys\n//\n//----------------------------------------------------------------------------\nvoid UnregisterAllHotkeys( HWND hWnd )\n{\n    UnregisterHotKey( hWnd, ZOOM_HOTKEY);\n    UnregisterHotKey( hWnd, LIVE_HOTKEY);\n    UnregisterHotKey( hWnd, LIVE_DRAW_HOTKEY);\n    UnregisterHotKey( hWnd, DRAW_HOTKEY);\n    UnregisterHotKey( hWnd, BREAK_HOTKEY);\n    UnregisterHotKey( hWnd, RECORD_HOTKEY);\n    UnregisterHotKey( hWnd, RECORD_CROP_HOTKEY );\n    UnregisterHotKey( hWnd, RECORD_WINDOW_HOTKEY );\n    UnregisterHotKey( hWnd, SNIP_HOTKEY );\n    UnregisterHotKey( hWnd, SNIP_SAVE_HOTKEY);\n    UnregisterHotKey( hWnd, DEMOTYPE_HOTKEY );\n    UnregisterHotKey( hWnd, DEMOTYPE_RESET_HOTKEY );\n}\n\n//----------------------------------------------------------------------------\n//\n// RegisterAllHotkeys\n//\n//----------------------------------------------------------------------------\nvoid RegisterAllHotkeys(HWND hWnd)\n{\n    if (g_ToggleKey) \t\t\tRegisterHotKey(hWnd, ZOOM_HOTKEY, g_ToggleMod, g_ToggleKey & 0xFF);\n    if (g_LiveZoomToggleKey) {\n        RegisterHotKey(hWnd, LIVE_HOTKEY, g_LiveZoomToggleMod, g_LiveZoomToggleKey & 0xFF);\n        RegisterHotKey(hWnd, LIVE_DRAW_HOTKEY, (g_LiveZoomToggleMod ^ MOD_SHIFT), g_LiveZoomToggleKey & 0xFF);\n    }\n    if (g_DrawToggleKey) \t\tRegisterHotKey(hWnd, DRAW_HOTKEY, g_DrawToggleMod, g_DrawToggleKey & 0xFF);\n    if (g_BreakToggleKey) \t\tRegisterHotKey(hWnd, BREAK_HOTKEY, g_BreakToggleMod, g_BreakToggleKey & 0xFF);\n    if (g_DemoTypeToggleKey) {\n        RegisterHotKey(hWnd, DEMOTYPE_HOTKEY, g_DemoTypeToggleMod, g_DemoTypeToggleKey & 0xFF);\n        RegisterHotKey(hWnd, DEMOTYPE_RESET_HOTKEY, (g_DemoTypeToggleMod ^ MOD_SHIFT), g_DemoTypeToggleKey & 0xFF);\n    }\n    if (g_SnipToggleKey) {\n        RegisterHotKey(hWnd, SNIP_HOTKEY, g_SnipToggleMod, g_SnipToggleKey & 0xFF);\n        RegisterHotKey(hWnd, SNIP_SAVE_HOTKEY, (g_SnipToggleMod ^ MOD_SHIFT), g_SnipToggleKey & 0xFF);\n    }\n    if (g_RecordToggleKey) {\n        RegisterHotKey(hWnd, RECORD_HOTKEY, g_RecordToggleMod | MOD_NOREPEAT, g_RecordToggleKey & 0xFF);\n        RegisterHotKey(hWnd, RECORD_CROP_HOTKEY, (g_RecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF);\n        RegisterHotKey(hWnd, RECORD_WINDOW_HOTKEY, (g_RecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF);\n    }\n}\n\n\n\n//----------------------------------------------------------------------------\n//\n// UpdateDrawTabHeaderFont\n//\n//----------------------------------------------------------------------------\nvoid UpdateDrawTabHeaderFont()\n{\n    static HFONT\theaderFont = nullptr;\n    TCHAR \t\t\ttext[64];\n\n    if( headerFont != nullptr )\n    {\n        DeleteObject( headerFont );\n        headerFont = nullptr;\n    }\n\n    constexpr int headers[] = { IDC_PEN_CONTROL, IDC_COLORS, IDC_HIGHLIGHT_AND_BLUR, IDC_SHAPES, IDC_SCREEN };\n    for( int i = 0; i < _countof( headers ); i++ )\n    {\n        // Change the header font to bold\n        HWND hHeader = GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, headers[i] );\n        if( headerFont == nullptr )\n        {\n            HFONT hFont = reinterpret_cast<HFONT>(SendMessage( hHeader, WM_GETFONT, 0, 0 ));\n            LOGFONT lf = {};\n            GetObject( hFont, sizeof( LOGFONT ), &lf );\n            lf.lfWeight = FW_BOLD;\n            headerFont = CreateFontIndirect( &lf );\n        }\n        SendMessage( hHeader, WM_SETFONT, reinterpret_cast<WPARAM>(headerFont), 0 );\n\n        // Resize the control to fit the text\n        GetWindowText( hHeader, text, sizeof( text ) / sizeof( text[0] ) );\n        RECT rc;\n        GetWindowRect( hHeader, &rc );\n        MapWindowPoints( NULL, g_OptionsTabs[DRAW_PAGE].hPage, reinterpret_cast<LPPOINT>(&rc), 2 );\n        HDC hDC = GetDC( hHeader );\n        SelectFont( hDC, headerFont );\n        DrawText( hDC, text, static_cast<int>(_tcslen( text )), &rc, DT_CALCRECT | DT_SINGLELINE | DT_LEFT | DT_VCENTER );\n        ReleaseDC( hHeader, hDC );\n        SetWindowPos( hHeader, nullptr, 0, 0, rc.right - rc.left + ScaleForDpi( 4, GetDpiForWindowHelper( hHeader ) ), rc.bottom - rc.top, SWP_NOMOVE | SWP_NOZORDER );\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// OptionsProc\n//\n//----------------------------------------------------------------------------\nINT_PTR CALLBACK OptionsProc( HWND hDlg, UINT message, \n                             WPARAM wParam, LPARAM lParam ) \n{\n    static HFONT\thFontBold = nullptr;\n    PNMLINK\t\t\tnotify = nullptr;\n    static int\t\tcurTabSel = 0;\n    static HWND\t\thTabCtrl;\n    static HWND\t\thOpacity;\n    static HWND\t\thToggleKey;\n    TCHAR\t\t\ttext[32];\n    DWORD\t\t\tnewToggleKey, newTimeout, newToggleMod, newBreakToggleKey, newDemoTypeToggleKey, newRecordToggleKey, newSnipToggleKey;\n    DWORD\t\t\tnewDrawToggleKey, newDrawToggleMod, newBreakToggleMod, newDemoTypeToggleMod, newRecordToggleMod, newSnipToggleMod;\n    DWORD\t\t\tnewLiveZoomToggleKey, newLiveZoomToggleMod;\n    static std::vector<std::pair<std::wstring, std::wstring>>\tmicrophones;\n\n    switch ( message )  {\n    case WM_INITDIALOG:\n    {\n        if( hWndOptions ) {\n\n            BringWindowToTop( hWndOptions );\n            SetFocus( hWndOptions );\n            SetForegroundWindow( hWndOptions );\n            EndDialog( hDlg, 0 );\n            return FALSE;\n        }\n        hWndOptions = hDlg;\n\n        SetForegroundWindow( hDlg );\n        SetActiveWindow( hDlg );\n        SetWindowPos( hDlg, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW ); \n#if 1\n        // set version info\n        TCHAR               filePath[MAX_PATH];\n        const TCHAR* verString;\n\n        GetModuleFileName(NULL, filePath, _countof(filePath));\n        DWORD               zero = 0;\n        DWORD               infoSize = GetFileVersionInfoSize(filePath, &zero);\n        void* versionInfo = malloc(infoSize);\n        GetFileVersionInfo(filePath, 0, infoSize, versionInfo);\n\n        verString = GetVersionString(static_cast<VERSION_INFO*>(versionInfo), _T(\"FileVersion\"));\n        SetDlgItemText(hDlg, IDC_VERSION, (std::wstring(L\"ZoomIt v\") + verString).c_str());\n\n        // verString = GetVersionString(static_cast<VERSION_INFO*>(versionInfo), _T(\"LegalCopyright\"));\n        verString = _T(\"版权所有 (C) Microsoft Corporation。保留所有权利。\");\n        SetDlgItemText(hDlg, IDC_COPYRIGHT, verString);\n\n        free(versionInfo);\n#endif\n        // Add tabs\n        hTabCtrl = GetDlgItem( hDlg, IDC_TAB );\n        OptionsAddTabs( hDlg, hTabCtrl );\n\n        InitializeFonts( hDlg, &hFontBold );\n        UpdateDrawTabHeaderFont();\n\n        // Configure options\n        SendMessage( GetDlgItem( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_HOTKEY), HKM_SETRULES, \n            static_cast<WPARAM>(HKCOMB_NONE), // invalid key combinations \n            MAKELPARAM(HOTKEYF_ALT, 0));     // add ALT to invalid entries \n\n        if( g_ToggleKey )\t\tSendMessage( GetDlgItem( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_HOTKEY), HKM_SETHOTKEY, g_ToggleKey, 0 );\n        if( pMagInitialize ) {\n\n            if( g_LiveZoomToggleKey )\tSendMessage( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_LIVE_HOTKEY), HKM_SETHOTKEY, g_LiveZoomToggleKey, 0 );\n\n        } else {\n\n            EnableWindow( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_LIVE_HOTKEY), FALSE );\n            EnableWindow( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_ZOOM_LEVEL), FALSE );\n            EnableWindow( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_ZOOM_SPIN), FALSE );\n        }\n        if( g_DrawToggleKey )\tSendMessage( GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_DRAW_HOTKEY), HKM_SETHOTKEY, g_DrawToggleKey, 0 );\n        if( g_BreakToggleKey )\tSendMessage( GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_BREAK_HOTKEY), HKM_SETHOTKEY, g_BreakToggleKey, 0 );\n        if( g_DemoTypeToggleKey ) SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_HOTKEY ), HKM_SETHOTKEY, g_DemoTypeToggleKey, 0 );\n        if( g_RecordToggleKey )\tSendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_HOTKEY), HKM_SETHOTKEY, g_RecordToggleKey, 0 );\n        if( g_SnipToggleKey) \tSendMessage( GetDlgItem( g_OptionsTabs[SNIP_PAGE].hPage, IDC_SNIP_HOTKEY), HKM_SETHOTKEY, g_SnipToggleKey, 0 );\n        CheckDlgButton( hDlg, IDC_SHOW_TRAY_ICON, \n            g_ShowTrayIcon ? BST_CHECKED: BST_UNCHECKED );\n        CheckDlgButton( hDlg, IDC_AUTOSTART, \n            IsAutostartConfigured() ? BST_CHECKED: BST_UNCHECKED );\n        CheckDlgButton( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ANIMATE_ZOOM, \n            g_AnimateZoom ? BST_CHECKED: BST_UNCHECKED );\n\n        SendMessage( GetDlgItem(g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ZOOM_SLIDER), TBM_SETRANGE, false, MAKELONG(0,_countof(g_ZoomLevels)-1) );\n        SendMessage( GetDlgItem(g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ZOOM_SLIDER), TBM_SETPOS, true, g_SliderZoomLevel );\n\n        _stprintf( text, L\"%d\", g_PenWidth );\n        SetDlgItemText( g_OptionsTabs[DRAW_PAGE].hPage, IDC_PEN_WIDTH, text );\n        SendMessage( GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_PEN_WIDTH ), EM_LIMITTEXT, 1, 0 );\n        SendMessage (GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_SPIN), UDM_SETRANGE, 0L, \n                            MAKELPARAM (19, 1));\n\n        _stprintf( text, L\"%d\", g_BreakTimeout );\n        SetDlgItemText( g_OptionsTabs[BREAK_PAGE].hPage, IDC_TIMER, text );\n        SendMessage( GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_TIMER ), EM_LIMITTEXT, 2, 0 );\n        SendMessage (GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_SPIN_TIMER), UDM_SETRANGE, 0L, \n                            MAKELPARAM (99, 1));\n        CheckDlgButton( g_OptionsTabs[BREAK_PAGE].hPage, IDC_CHECK_SHOW_EXPIRED,\n            g_ShowExpiredTime ? BST_CHECKED : BST_UNCHECKED );\n\n        CheckDlgButton( g_OptionsTabs[RECORD_PAGE].hPage, IDC_CAPTURE_AUDIO, \n            g_CaptureAudio ? BST_CHECKED: BST_UNCHECKED );\n\n        for (int i = 0; i < _countof(g_FramerateOptions); i++) {\n\n            _stprintf(text, L\"%d\", g_FramerateOptions[i]);\n            SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), static_cast<UINT>(CB_ADDSTRING),\n                static_cast<WPARAM>(0), reinterpret_cast<LPARAM>(text));\n            if (g_RecordFrameRate == g_FramerateOptions[i]) {\n\n                SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), CB_SETCURSEL, static_cast<WPARAM>(i), static_cast<LPARAM>(0));\n            }\n        }\n        for(unsigned int i = 1; i < 11; i++) {\n\n            _stprintf(text, L\"%2.1f\", (static_cast<double>(i)) / 10 );\n            SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), static_cast<UINT>(CB_ADDSTRING),\n                static_cast<WPARAM>(0), reinterpret_cast<LPARAM>(text));\n            if (g_RecordScaling == i*10 ) {\n\n                SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), CB_SETCURSEL, static_cast<WPARAM>(i)-1, static_cast<LPARAM>(0));\n            }\n        }\n\n        // Get the current set of microphones\n        microphones.clear();\n        concurrency::create_task([]{\n            auto devices = winrt::DeviceInformation::FindAllAsync( winrt::DeviceClass::AudioCapture ).get();\n            for( auto device : devices )\n            {\n                microphones.emplace_back( device.Id().c_str(), device.Name().c_str() );\n            }\n        }).get();\n\n        // Add the microphone devices to the combo box and set the current selection\n        SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), static_cast<UINT>(CB_ADDSTRING), static_cast<WPARAM>(0), reinterpret_cast<LPARAM>(L\"默认麦克风\"));\n        size_t selection = 0;\n        for( size_t i = 0; i < microphones.size(); i++ )\n        {\n            SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), static_cast<UINT>(CB_ADDSTRING), static_cast<WPARAM>(0), reinterpret_cast<LPARAM>(microphones[i].second.c_str()) );\n            if( selection == 0 && wcscmp( microphones[i].first.c_str(), g_MicrophoneDeviceId ) == 0 )\n            {\n                selection = i + 1;\n            }\n        }\n        SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), CB_SETCURSEL, static_cast<WPARAM>(selection), static_cast<LPARAM>(0) );\n\n        if( GetFileAttributes( g_DemoTypeFile ) == -1 )\n        {\n            memset( g_DemoTypeFile, 0, sizeof( g_DemoTypeFile ) );\n        }\n        else\n        {\n            SetDlgItemText( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_FILE, g_DemoTypeFile );\n        }\n        SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_SPEED_SLIDER ), TBM_SETRANGE, false, MAKELONG( MAX_TYPING_SPEED, MIN_TYPING_SPEED ) );\n        SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_SPEED_SLIDER ), TBM_SETPOS, true, g_DemoTypeSpeedSlider );\n        CheckDlgButton( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_USER_DRIVEN, g_DemoTypeUserDriven ? BST_CHECKED: BST_UNCHECKED );\n\n        UnregisterAllHotkeys(GetParent( hDlg ));\n        PostMessage( hDlg, WM_USER, 0, 0 );\n        return TRUE;\n    }\n\n    case WM_USER+100:\n        BringWindowToTop( hDlg );\n        SetFocus( hDlg );\n        SetForegroundWindow( hDlg );\n        return TRUE;\n\n    case WM_DPICHANGED:\n        InitializeFonts( hDlg, &hFontBold );\n        UpdateDrawTabHeaderFont();\n        break;\n\n    case WM_CTLCOLORSTATIC:\n        if( reinterpret_cast<HWND>(lParam) == GetDlgItem( hDlg, IDC_TITLE ) || \n            reinterpret_cast<HWND>(lParam) == GetDlgItem(hDlg, IDC_DRAWING) ||\n            reinterpret_cast<HWND>(lParam) == GetDlgItem(hDlg, IDC_ZOOM) ||\n            reinterpret_cast<HWND>(lParam) == GetDlgItem(hDlg, IDC_BREAK) ||\n            reinterpret_cast<HWND>(lParam) == GetDlgItem( hDlg, IDC_TYPE )) {\n\n            HDC\thdc = reinterpret_cast<HDC>(wParam);\n            SetBkMode( hdc, TRANSPARENT );\n            SelectObject( hdc, hFontBold );\n            return PtrToLong(GetSysColorBrush( COLOR_BTNFACE ));\n        }\n        break;\n\n    case WM_NOTIFY:\n        notify = reinterpret_cast<PNMLINK>(lParam);\n        if( notify->hdr.idFrom == IDC_LINK )\n        {\n            switch( notify->hdr.code )\n            {\n            case NM_CLICK:\n            case NM_RETURN:\n                ShellExecute( hDlg, _T(\"open\"), notify->item.szUrl, NULL, NULL, SW_SHOWNORMAL );\n                break;\n            }\n        }\n        else switch( notify->hdr.code )\n        {\n        case TCN_SELCHANGE:\n            ShowWindow( g_OptionsTabs[curTabSel].hPage, SW_HIDE );\n            curTabSel = TabCtrl_GetCurSel(hTabCtrl);\n            ShowWindow( g_OptionsTabs[curTabSel].hPage, SW_SHOW );\n            break;\n        }\n        break;\n\n    case WM_COMMAND:\n        switch ( LOWORD( wParam )) {\n        case IDOK:\n        {\n            if( !ConfigureAutostart( hDlg, IsDlgButtonChecked( hDlg, IDC_AUTOSTART) == BST_CHECKED )) {\n\n                break;\n            }\n            g_ShowTrayIcon = IsDlgButtonChecked( hDlg, IDC_SHOW_TRAY_ICON ) == BST_CHECKED;\n            g_AnimateZoom = IsDlgButtonChecked( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ANIMATE_ZOOM ) == BST_CHECKED;\n            g_DemoTypeUserDriven = IsDlgButtonChecked( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_USER_DRIVEN ) == BST_CHECKED;\n\n            newToggleKey = static_cast<DWORD>(SendMessage( GetDlgItem( g_OptionsTabs[ZOOM_PAGE].hPage, IDC_HOTKEY), HKM_GETHOTKEY, 0, 0 ));\n            newLiveZoomToggleKey = static_cast<DWORD>(SendMessage( GetDlgItem( g_OptionsTabs[LIVE_PAGE].hPage, IDC_LIVE_HOTKEY), HKM_GETHOTKEY, 0, 0 ));\n            newDrawToggleKey = static_cast<DWORD>(SendMessage( GetDlgItem( g_OptionsTabs[DRAW_PAGE].hPage, IDC_DRAW_HOTKEY), HKM_GETHOTKEY, 0, 0 ));\n            newBreakToggleKey = static_cast<DWORD>(SendMessage( GetDlgItem( g_OptionsTabs[BREAK_PAGE].hPage, IDC_BREAK_HOTKEY), HKM_GETHOTKEY, 0, 0 ));\n            newDemoTypeToggleKey = static_cast<DWORD>(SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_HOTKEY ), HKM_GETHOTKEY, 0, 0 ));\n            newRecordToggleKey = static_cast<DWORD>(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_HOTKEY), HKM_GETHOTKEY, 0, 0));\n            newSnipToggleKey = static_cast<DWORD>(SendMessage( GetDlgItem( g_OptionsTabs[SNIP_PAGE].hPage, IDC_SNIP_HOTKEY), HKM_GETHOTKEY, 0, 0 ));\n\n            newToggleMod = GetKeyMod( newToggleKey );\n            newLiveZoomToggleMod = GetKeyMod( newLiveZoomToggleKey );\n            newDrawToggleMod = GetKeyMod( newDrawToggleKey );\n            newBreakToggleMod = GetKeyMod( newBreakToggleKey );\n            newDemoTypeToggleMod = GetKeyMod( newDemoTypeToggleKey );\n            newRecordToggleMod = GetKeyMod(newRecordToggleKey);\n            newSnipToggleMod = GetKeyMod( newSnipToggleKey );\n\n            g_SliderZoomLevel = static_cast<int>(SendMessage( GetDlgItem(g_OptionsTabs[ZOOM_PAGE].hPage, IDC_ZOOM_SLIDER), TBM_GETPOS, 0, 0 ));\n            g_DemoTypeSpeedSlider = static_cast<int>(SendMessage( GetDlgItem( g_OptionsTabs[DEMOTYPE_PAGE].hPage, IDC_DEMOTYPE_SPEED_SLIDER ), TBM_GETPOS, 0, 0 ));\n\n            g_ShowExpiredTime = IsDlgButtonChecked(  g_OptionsTabs[BREAK_PAGE].hPage, IDC_CHECK_SHOW_EXPIRED ) == BST_CHECKED;\n            g_CaptureAudio = IsDlgButtonChecked(g_OptionsTabs[RECORD_PAGE].hPage, IDC_CAPTURE_AUDIO) == BST_CHECKED;\n            GetDlgItemText( g_OptionsTabs[BREAK_PAGE].hPage, IDC_TIMER, text, 3 );\n            text[2] = 0;\n            newTimeout = _tstoi( text );\n\n            g_RecordFrameRate = g_FramerateOptions[SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_FRAME_RATE), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0))];\n            g_RecordScaling = static_cast<int>(SendMessage(GetDlgItem(g_OptionsTabs[RECORD_PAGE].hPage, IDC_RECORD_SCALING), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0)) * 10 + 10);\n\n            // Get the selected microphone\n            int index = static_cast<int>(SendMessage( GetDlgItem( g_OptionsTabs[RECORD_PAGE].hPage, IDC_MICROPHONE ), static_cast<UINT>(CB_GETCURSEL), static_cast<WPARAM>(0), static_cast<LPARAM>(0) ));\n            _tcscpy( g_MicrophoneDeviceId, index == 0 ? L\"\" : microphones[static_cast<size_t>(index) - 1].first.c_str() );\n\n            if( newToggleKey && !RegisterHotKey( GetParent( hDlg ), ZOOM_HOTKEY, newToggleMod, newToggleKey & 0xFF )) {\n\n                MessageBox( hDlg, L\"此快捷键已被占用。\\n请重新选择放大快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                UnregisterAllHotkeys(GetParent( hDlg ));\n                break;\n\n            } else if(newLiveZoomToggleKey && \n                (!RegisterHotKey( GetParent( hDlg ), LIVE_HOTKEY, newLiveZoomToggleMod, newLiveZoomToggleKey & 0xFF ) ||\n                !RegisterHotKey(GetParent(hDlg), LIVE_DRAW_HOTKEY, (newLiveZoomToggleMod ^ MOD_SHIFT), newLiveZoomToggleKey & 0xFF))) {\n\n                MessageBox( hDlg, L\"此快捷键已被占用。\\n请重新选择实时放大快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                UnregisterAllHotkeys(GetParent( hDlg ));\n                break;\n\n            } else if( newDrawToggleKey && !RegisterHotKey( GetParent( hDlg ), DRAW_HOTKEY, newDrawToggleMod, newDrawToggleKey & 0xFF )) {\n\n                MessageBox( hDlg, L\"此快捷键已被占用。\\n请重新选择画图快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                UnregisterAllHotkeys(GetParent( hDlg ));\n                break;\n\n            } else if( newBreakToggleKey && !RegisterHotKey( GetParent( hDlg ), BREAK_HOTKEY, newBreakToggleMod, newBreakToggleKey & 0xFF )) {\n\n                MessageBox( hDlg, L\"此快捷键已被占用。\\n请重新选择倒计时快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                UnregisterAllHotkeys(GetParent( hDlg ));\n                break;\n\n            } else if( newDemoTypeToggleKey && \n                (!RegisterHotKey( GetParent( hDlg ), DEMOTYPE_HOTKEY, newDemoTypeToggleMod, newDemoTypeToggleKey & 0xFF ) ||\n                    !RegisterHotKey(GetParent(hDlg), DEMOTYPE_RESET_HOTKEY, (newDemoTypeToggleMod ^ MOD_SHIFT), newDemoTypeToggleKey & 0xFF))) {\n\n                MessageBox( hDlg, L\"此快捷键已被占用。\\n请重新选择自动打字快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                UnregisterAllHotkeys( GetParent( hDlg ) );\n                break;\n\n            }\n            else if (newSnipToggleKey && \n                (!RegisterHotKey(GetParent(hDlg), SNIP_HOTKEY, newSnipToggleMod, newSnipToggleKey & 0xFF) ||\n                 !RegisterHotKey(GetParent(hDlg), SNIP_SAVE_HOTKEY, (newSnipToggleMod ^ MOD_SHIFT), newSnipToggleKey & 0xFF))) {\n\n                MessageBox(hDlg, L\"此快捷键已被占用。\\n请重新选择截图快捷键。\",\n                    APPNAME, MB_ICONERROR);\n                UnregisterAllHotkeys(GetParent(hDlg));\n                break;\n\n            }\t\t\t\n            else if( newRecordToggleKey && \n                (!RegisterHotKey(GetParent(hDlg), RECORD_HOTKEY,      newRecordToggleMod | MOD_NOREPEAT, newRecordToggleKey & 0xFF) ||\n                 !RegisterHotKey(GetParent(hDlg), RECORD_CROP_HOTKEY, (newRecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, newRecordToggleKey & 0xFF) ||\n                 !RegisterHotKey(GetParent(hDlg), RECORD_WINDOW_HOTKEY, (newRecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, newRecordToggleKey & 0xFF))) {\n\n                MessageBox(hDlg, L\"此快捷键已被占用。\\n请重新选择录屏快捷键。\",\n                    APPNAME, MB_ICONERROR);\n                UnregisterAllHotkeys(GetParent(hDlg));\n                break;\n\n            } else {\n        \n                g_BreakTimeout = newTimeout;\n                g_ToggleKey = newToggleKey;\n                g_LiveZoomToggleKey = newLiveZoomToggleKey;\n                g_ToggleMod = newToggleMod;\n                g_DrawToggleKey = newDrawToggleKey;\n                g_DrawToggleMod = newDrawToggleMod;\n                g_BreakToggleKey = newBreakToggleKey;\n                g_BreakToggleMod = newBreakToggleMod;\n                g_DemoTypeToggleKey = newDemoTypeToggleKey;\n                g_DemoTypeToggleMod = newDemoTypeToggleMod;\n                g_RecordToggleKey = newRecordToggleKey;\n                g_RecordToggleMod = newRecordToggleMod;\n                g_SnipToggleKey = newSnipToggleKey;\n                g_SnipToggleMod = newSnipToggleMod;\n                reg.WriteRegSettings( RegSettings );\n                EnableDisableTrayIcon( GetParent( hDlg ), g_ShowTrayIcon );\n\n                hWndOptions = NULL;\n                EndDialog( hDlg, 0 );\n                return TRUE;\t\t\t\t\n            }\n            break;\n        }\n\n        case IDCANCEL:\n            RegisterAllHotkeys(GetParent(hDlg));\n            hWndOptions = NULL;\n            EndDialog( hDlg, 0 );\n            return TRUE;\n        }\n        break; \n        \n    case WM_CLOSE:\n        hWndOptions = NULL;\n        RegisterAllHotkeys(GetParent(hDlg));\n        EndDialog( hDlg, 0 );\n        return TRUE;\n\n    default:\n        break;\n    }\n    return FALSE;\n}\n\n//----------------------------------------------------------------------------\n//\n// DeleteDrawUndoList\n//\n//----------------------------------------------------------------------------\nvoid DeleteDrawUndoList( P_DRAW_UNDO *DrawUndoList )\n{\n    P_DRAW_UNDO\tnextUndo;\n\n    nextUndo = *DrawUndoList;\n    while( nextUndo ) {\n\n        *DrawUndoList = nextUndo->Next;\n        DeleteObject( nextUndo->hBitmap );\n        DeleteDC( nextUndo->hDc );\n        free( nextUndo );\n        nextUndo = *DrawUndoList;\n    }\n    *DrawUndoList = NULL;\n}\n\n//----------------------------------------------------------------------------\n//\n// PopDrawUndo\n//\n//----------------------------------------------------------------------------\nBOOLEAN PopDrawUndo( HDC hDc, P_DRAW_UNDO *DrawUndoList, \n                  int width, int height )\n{\n    P_DRAW_UNDO\tnextUndo;\n\n    nextUndo = *DrawUndoList;\n    if( nextUndo ) {\n\n        BitBlt( hDc, 0, 0, width, height, \n            nextUndo->hDc, 0, 0, SRCCOPY|CAPTUREBLT );\n        *DrawUndoList = nextUndo->Next;\n        DeleteObject( nextUndo->hBitmap );\n        DeleteDC( nextUndo->hDc );\n        free( nextUndo );\n        return TRUE;\n\n    } else {\n\n        Beep( 700, 200 );\n        return FALSE;\n    }\n}\n\n\n//----------------------------------------------------------------------------\n//\n// DeleteOldestUndo\n//\n//----------------------------------------------------------------------------\nvoid DeleteOldestUndo( P_DRAW_UNDO *DrawUndoList )\n{\n    P_DRAW_UNDO\tnextUndo, freeUndo = NULL, prevUndo = NULL;\n\n    nextUndo = *DrawUndoList;\n    freeUndo = nextUndo;\n    do {\n\n        prevUndo = freeUndo;\n        freeUndo = nextUndo;\n        nextUndo = nextUndo->Next;\n\n    } while( nextUndo );\n\n    if( freeUndo ) {\n\n        DeleteObject( freeUndo->hBitmap );\n        DeleteDC( freeUndo->hDc );\n        free( freeUndo );\n        if( prevUndo != *DrawUndoList ) prevUndo->Next = NULL;\n        else *DrawUndoList = NULL;\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// GetOldestUndo\n// \n//----------------------------------------------------------------------------\nP_DRAW_UNDO GetOldestUndo(P_DRAW_UNDO DrawUndoList)\n{\n    P_DRAW_UNDO\tnextUndo, oldestUndo = NULL;\n\n    nextUndo = DrawUndoList;\n    oldestUndo = nextUndo;\n    do {\n\n        oldestUndo = nextUndo;\n        nextUndo = nextUndo->Next;\n\n    } while( nextUndo );\n    return oldestUndo;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// PushDrawUndo\n//\n//----------------------------------------------------------------------------\nvoid PushDrawUndo( HDC hDc, P_DRAW_UNDO *DrawUndoList, int width, int height )\n{\n    P_DRAW_UNDO\tnextUndo, newUndo;\n    int\t\t\ti = 0;\n    HBITMAP\t\thUndoBitmap;\n\n    OutputDebug(L\"PushDrawUndo\\n\");\n\n    // Don't store more than 8 undo's (XP gets really upset when we\n    // exhaust heap with them)\n    nextUndo = *DrawUndoList;\n    do {\n\n        i++;\n        if( i == MAX_UNDO_HISTORY ) {\n\n            DeleteOldestUndo( DrawUndoList );\n            break;\n        }\n        if( nextUndo ) nextUndo = nextUndo->Next;\n\n    } while( nextUndo );\n\n    hUndoBitmap = CreateCompatibleBitmap( hDc, width, height );\n    if( !hUndoBitmap && *DrawUndoList ) {\n\n        // delete the oldest and try again\n        DeleteOldestUndo( DrawUndoList );\n        hUndoBitmap = CreateCompatibleBitmap( hDc, width, height );\n    }\n    if( hUndoBitmap ) {\n\n        newUndo = static_cast<P_DRAW_UNDO>(malloc( sizeof( DRAW_UNDO )));\n        if (newUndo != NULL)\n        {\n            newUndo->hDc = CreateCompatibleDC(hDc);\n            newUndo->hBitmap = hUndoBitmap;\n            SelectObject(newUndo->hDc, newUndo->hBitmap);\n            BitBlt(newUndo->hDc, 0, 0, width, height, hDc, 0, 0, SRCCOPY | CAPTUREBLT);\n            newUndo->Next = *DrawUndoList;\n            *DrawUndoList = newUndo;\n        }\n    } \n}\n\n//----------------------------------------------------------------------------\n//\n// DeleteTypedText\n//\n//----------------------------------------------------------------------------\nvoid DeleteTypedText( P_TYPED_KEY *TypedKeyList )\n{\n    P_TYPED_KEY\tnextKey;\n\n    while( *TypedKeyList ) {\n\n        nextKey = (*TypedKeyList)->Next;\n        free( *TypedKeyList );\n        *TypedKeyList = nextKey;\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// BlankScreenArea\n//\n//----------------------------------------------------------------------------\nvoid BlankScreenArea( HDC hDc, PRECT Rc, int BlankMode )\n{\n    if( BlankMode == 'K' ) {\n\n        HBRUSH hBrush = CreateSolidBrush( RGB( 0, 0, 0 ));\n        FillRect( hDc, Rc, hBrush );\n        DeleteObject( static_cast<HGDIOBJ>(hBrush) );\n\n    } else {\n\n        FillRect( hDc, Rc, GetSysColorBrush( COLOR_WINDOW ));\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// ClearTypingCursor\n//\n//----------------------------------------------------------------------------\nvoid ClearTypingCursor( HDC hdcScreenCompat, HDC hdcScreenCursorCompat, RECT rc,\n                            int BlankMode )\n{\n    if( false ) { // BlankMode ) {\n\n        BlankScreenArea( hdcScreenCompat, &rc, BlankMode );\n\n    } else {\n\n        BitBlt(hdcScreenCompat, rc.left, rc.top, rc.right - rc.left,  \n            rc.bottom - rc.top, hdcScreenCursorCompat,0, 0, SRCCOPY|CAPTUREBLT ); \n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// DrawTypingCursor\n//\n//----------------------------------------------------------------------------\nvoid DrawTypingCursor( HWND hWnd, POINT *textPt, HDC hdcScreenCompat,\n\tHDC hdcScreenCursorCompat, RECT *rc, bool centerUnderSystemCursor = false )\n{\n\t// Draw the typing cursor\n\trc->left = textPt->x;\n\trc->top = textPt->y;\n\tTCHAR vKey = '|';\n\tDrawText( hdcScreenCompat, static_cast<PTCHAR>(&vKey), 1, rc, DT_CALCRECT );\n\n\t// LiveDraw uses a layered window which means mouse messages pass through\n\t//   to lower windows unless the system cursor is above a painted area.\n\t// Centering the typing cursor directly under the system cursor allows\n\t//   us to capture the mouse wheel input required to change font size.\n\tif( centerUnderSystemCursor )\n\t{\n\t\tconst LONG halfWidth  = static_cast<LONG>( (rc->right - rc->left) / 2 );\n\t\tconst LONG halfHeight = static_cast<LONG>( (rc->bottom - rc->top) / 2 );\n\n\t\trc->left   -= halfWidth;\n\t\trc->right  -= halfWidth;\n\t\trc->top    -= halfHeight;\n\t\trc->bottom -= halfHeight;\n\n\t\ttextPt->x   = rc->left;\n\t\ttextPt->y   = rc->top;\n\t}\n\n\tBitBlt(hdcScreenCursorCompat, 0, 0, rc->right -rc->left, rc->bottom - rc->top,\n\t\thdcScreenCompat, rc->left, rc->top, SRCCOPY|CAPTUREBLT );\n\n\tDrawText( hdcScreenCompat, static_cast<PTCHAR>(&vKey), 1, rc, DT_LEFT );\n\tInvalidateRect( hWnd, NULL, TRUE );\n}\n\n//----------------------------------------------------------------------------\n//\n// BoundMouse\n//\n//----------------------------------------------------------------------------\nRECT BoundMouse( float zoomLevel, MONITORINFO *monInfo, int width, int height,\n                    POINT *cursorPos )\n{\n    RECT\t\trc;\n    int\t\t\tx, y;\n\n    GetZoomedTopLeftCoordinates( zoomLevel, cursorPos, &x, width, &y, height );\n    rc.left = monInfo->rcMonitor.left + x; \n    rc.right = rc.left + static_cast<int>(width/zoomLevel);\n    rc.top = monInfo->rcMonitor.top + y;\n    rc.bottom = rc.top + static_cast<int>(height/zoomLevel);\n\n    OutputDebug( L\"x: %d y: %d width: %d height: %d zoomLevel: %g\\n\",\n        cursorPos->x, cursorPos->y, width, height, zoomLevel);\n    OutputDebug( L\"left: %d top: %d right: %d bottom: %d\\n\",\n            rc.left, rc.top, rc.right, rc.bottom);\n    OutputDebug( L\"mon.left: %d mon.top: %d mon.right: %d mon.bottom: %d\\n\",\n        monInfo->rcMonitor.left, monInfo->rcMonitor.top, monInfo->rcMonitor.right, monInfo->rcMonitor.bottom);\n    \n    ClipCursor( &rc );\n    return rc;\n}\n\n//----------------------------------------------------------------------------\n//\n// DrawArrow\n//\n//----------------------------------------------------------------------------\nvoid DrawArrow( HDC hdc, int x1, int y1, int x2, int y2, double length, double width,\n        bool UseGdiplus )\n{\n    // get normalized dx/dy\n    double dx = static_cast<double>(x2) - x1;\n    double dy = static_cast<double>(y2) - y1;\n    double bodyLen = sqrt( dx*dx + dy*dy );\n    if ( bodyLen )  {\n        dx /= bodyLen;\n        dy /= bodyLen;\n    } else {\n        dx = 1;\n        dy = 0;\n    }\n\n    // get midpoint of base\n    int xMid = x2 - static_cast<int>(length*dx+0.5);\n    int yMid = y2 - static_cast<int>(length*dy+0.5);\n    \n    // get left wing\n    int xLeft = xMid - static_cast<int>(dy*width+0.5);\n    int yLeft = yMid + static_cast<int>(dx*width+0.5);\n\n    // get right wing\n    int xRight = xMid + static_cast<int>(dy*width+0.5);\n    int yRight = yMid - static_cast<int>(dx*width+0.5);\n\n    // Bring in midpoint to make a nicer arrow\n    xMid = x2 - static_cast<int>(length/2*dx+0.5);\n    yMid = y2 - static_cast<int>(length/2*dy+0.5);\n    if (UseGdiplus) {\n\n        Gdiplus::Graphics\tdstGraphics(hdc);\n\n        if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n        {\n            dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n        }\n        Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n        Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n        pen.SetLineCap(Gdiplus::LineCapRound, Gdiplus::LineCapRound, Gdiplus::DashCapRound);\n#if 0\n        Gdiplus::PointF\tpts[] = {\n            {(Gdiplus::REAL)x1, (Gdiplus::REAL)y1},\n            {(Gdiplus::REAL)xMid, (Gdiplus::REAL)yMid},\n            {(Gdiplus::REAL)xLeft, (Gdiplus::REAL)yLeft},\n            {(Gdiplus::REAL)x2, (Gdiplus::REAL)y2},\n            {(Gdiplus::REAL)xRight, (Gdiplus::REAL)yRight},\n            {(Gdiplus::REAL)xMid, (Gdiplus::REAL)yMid}\n        };\n        dstGraphics.DrawPolygon(&pen, pts, _countof(pts));\n#else\n        Gdiplus::GraphicsPath path;\n        path.StartFigure();\n        path.AddLine(static_cast<INT>(x1), static_cast<INT>(y1), static_cast<INT>(x2), static_cast<INT>(y2));\n        path.AddLine(static_cast<INT>(x2), static_cast<INT>(y2), static_cast<INT>(xMid), static_cast<INT>(yMid));\n        path.AddLine(static_cast<INT>(xMid), static_cast<INT>(yMid), static_cast<INT>(xLeft), static_cast<INT>(yLeft));\n        path.AddLine(static_cast<INT>(xLeft), static_cast<INT>(yLeft), static_cast<INT>(x2), static_cast<INT>(y2));\n        path.AddLine(static_cast<INT>(x2), static_cast<INT>(y2), static_cast<INT>(xRight), static_cast<INT>(yRight));\n        path.AddLine(static_cast<INT>(xRight), static_cast<INT>(yRight), static_cast<INT>(xMid), static_cast<INT>(yMid));\n        pen.SetLineJoin(Gdiplus::LineJoinRound);\n        dstGraphics.DrawPath(&pen, &path);\n#endif\n    }\n    else {\n        POINT\tpts[] = {\n            x1, y1,\n            xMid, yMid,\n            xLeft, yLeft,\n            x2, y2,\n            xRight, yRight,\n            xMid, yMid\n        };\n\n        // draw arrow head filled with current color\n        HBRUSH hBrush = CreateSolidBrush(g_PenColor);\n        HBRUSH hOldBrush = SelectBrush(hdc, hBrush);\n        Polygon(hdc, pts, sizeof(pts) / sizeof(pts[0]));\n\n        DeleteObject(hBrush);\n        SelectObject(hdc, hOldBrush);\n    }\n}\n\n\n\n//----------------------------------------------------------------------------\n//\n// DrawShape\n//\n//----------------------------------------------------------------------------\nVOID DrawShape( DWORD Shape, HDC hDc, RECT *Rect, bool UseGdiPlus = false )\n{\n    bool\tisBlur = false;\n\n    Gdiplus::Graphics\tdstGraphics(hDc);\n\n\tif( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n\t{\n\t\tdstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n\t}\n    Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n    Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n    pen.SetLineCap(Gdiplus::LineCapRound, Gdiplus::LineCapRound, Gdiplus::DashCapRound);\n\n    // Check for highlighting or blur\n    Gdiplus::Brush *pBrush = NULL;\n    if (PEN_COLOR_HIGHLIGHT(g_PenColor)) {\n        // Use half the alpha for higher contrast\n        DWORD newColor = g_PenColor & 0xFFFFFF | ((g_AlphaBlend / 2) << 24);\n        pBrush = new Gdiplus::SolidBrush(ColorFromColorRef(newColor));\n        if(UseGdiPlus && Shape != DRAW_LINE && Shape != DRAW_ARROW)\n            InflateRect(Rect, g_PenWidth/2, g_PenWidth/2);\n    }\n    else if ((g_PenColor & 0xFFFFFF) == COLOR_BLUR) {\n        if (UseGdiPlus && Shape != DRAW_LINE && Shape != DRAW_ARROW)\n            InflateRect(Rect, g_PenWidth / 2, g_PenWidth / 2);\n        isBlur = true;\n    }\n\n    switch (Shape) {\n    case DRAW_RECTANGLE:\n        if (UseGdiPlus)\n            if(pBrush)\n                DrawHighlightedShape(DRAW_RECTANGLE, hDc, pBrush, NULL, \n                    static_cast<int>(Rect->left - 1), static_cast<int>(Rect->top - 1),\n                    static_cast<int>(Rect->right), static_cast<int>(Rect->bottom));\n            else if (isBlur)\n                DrawBlurredShape( DRAW_RECTANGLE, &pen, hDc, &dstGraphics,\n                    static_cast<int>(Rect->left - 1), static_cast<int>(Rect->top - 1),\n                    static_cast<int>(Rect->right), static_cast<int>(Rect->bottom) );\n            else\n                dstGraphics.DrawRectangle(&pen,\n                    Gdiplus::Rect::Rect(Rect->left - 1, Rect->top - 1,\n                        Rect->right - Rect->left, Rect->bottom - Rect->top));\n        else\n            Rectangle(hDc, Rect->left, Rect->top,\n                Rect->right, Rect->bottom);\n        break;\n    case DRAW_ELLIPSE:\n        if (UseGdiPlus)\n            if (pBrush)\n                DrawHighlightedShape(DRAW_ELLIPSE, hDc, pBrush, NULL,\n                    static_cast<int>(Rect->left - 1), static_cast<int>(Rect->top - 1),\n                    static_cast<int>(Rect->right), static_cast<int>(Rect->bottom));\n            else if (isBlur)\n                DrawBlurredShape( DRAW_ELLIPSE, &pen, hDc, &dstGraphics,\n                    static_cast<int>(Rect->left - 1), static_cast<int>(Rect->top - 1),\n                    static_cast<int>(Rect->right), static_cast<int>(Rect->bottom));\n            else\n                dstGraphics.DrawEllipse(&pen,\n                    Gdiplus::Rect::Rect(Rect->left - 1, Rect->top - 1,\n                        Rect->right - Rect->left, Rect->bottom - Rect->top));\n        else\n            Ellipse(hDc, Rect->left, Rect->top,\n                Rect->right, Rect->bottom);\n        break;\n    case DRAW_LINE:\n        if (UseGdiPlus)\n            if (pBrush)\n                DrawHighlightedShape(DRAW_LINE, hDc, NULL, &pen,\n                    static_cast<int>(Rect->left), static_cast<int>(Rect->top),\n                    static_cast<int>(Rect->right), static_cast<int>(Rect->bottom));\n            else if (isBlur)\n                DrawBlurredShape(DRAW_LINE, &pen, hDc, &dstGraphics,\n                    static_cast<int>(Rect->left), static_cast<int>(Rect->top),\n                    static_cast<int>(Rect->right), static_cast<int>(Rect->bottom));\n            else\n                dstGraphics.DrawLine(&pen,\n                    static_cast<INT>(Rect->left - 1), static_cast<INT>(Rect->top - 1),\n                    static_cast<INT>(Rect->right), static_cast<INT>(Rect->bottom));\n        else {\n            MoveToEx(hDc, Rect->left, Rect->top, NULL);\n            LineTo(hDc, Rect->right + 1, Rect->bottom + 1);\n        }\n        break;\n    case DRAW_ARROW:\n        DrawArrow(hDc, Rect->right + 1, Rect->bottom + 1,\n            Rect->left, Rect->top,\n            static_cast<double>(g_PenWidth) * 2.5, static_cast<double>(g_PenWidth) * 1.5, UseGdiPlus);\n        break;\n    }\n    if( pBrush ) delete pBrush;\n}\n\n//----------------------------------------------------------------------------\n//\n// SendPenMessage\n//\n// Inserts the pen message marker.\n//\n//----------------------------------------------------------------------------\nVOID SendPenMessage(HWND hWnd, UINT Message, LPARAM lParam)\n{\n    WPARAM\t\twParam = 0;\n    //\n    // Get key states\n    //\n    if(GetKeyState(VK_LCONTROL) < 0 ) {\n\n        wParam |= MK_CONTROL;\n    } \n    if( GetKeyState( VK_LSHIFT) < 0 || GetKeyState( VK_RSHIFT) < 0 ) {\n\n        wParam |= MK_SHIFT;\n    }\n    SetMessageExtraInfo(static_cast<LPARAM>(MI_WP_SIGNATURE));\n    SendMessage(hWnd, Message, wParam, lParam);\n}\n\n\n//----------------------------------------------------------------------------\n//\n// ScalePenPosition\n// \n// Maps pen input to mouse input coordinates based on zoom level. Returns\n// 0 if pen is active but we didn't send this message to ourselves (pen\n// signature will be missing). \n//\n//----------------------------------------------------------------------------\nLPARAM ScalePenPosition( float zoomLevel, MONITORINFO *monInfo, RECT boundRc,\n                    UINT message, LPARAM lParam )\n{\n    RECT\trc;\n    WORD\tx, y;\n    LPARAM\textraInfo;\n\n    extraInfo = GetMessageExtraInfo();\n    if( g_PenDown ) { \n\n        // ignore messages we didn't tag as pen\n        if (extraInfo == MI_WP_SIGNATURE) {\n\n            OutputDebug( L\"Tablet Pen message\\n\");\n\n            // tablet input: don't bound the cursor\n            ClipCursor(NULL);\n\n            x = LOWORD(lParam);\n            y = HIWORD(lParam);\n\n            x = static_cast<WORD>((x - static_cast<WORD>(monInfo->rcMonitor.left))/ zoomLevel) + static_cast<WORD>(boundRc.left - monInfo->rcMonitor.left);\n            y = static_cast<WORD>((y - static_cast<WORD>(monInfo->rcMonitor.top)) / zoomLevel) + static_cast<WORD>(boundRc.top - monInfo->rcMonitor.top);\n\n            lParam = MAKELPARAM(x, y);\n        }\n        else {\n\n            OutputDebug(L\"Ignore pen message we didn't send\\n\");\n            lParam = 0;\n        }\n    \n    } else {\n\n        if( !GetClipCursor( &rc )) {\n\n            ClipCursor( &boundRc );\n        }\n        OutputDebug( L\"Mouse message\\n\");\n    }\n    return lParam;\n} \n\n\n//----------------------------------------------------------------------------\n//\n// DrawHighlightedCursor\n//\n//----------------------------------------------------------------------------\nBOOLEAN DrawHighlightedCursor( float ZoomLevel, int Width, int Height )\n{\n    DWORD zoomWidth = static_cast<DWORD> (static_cast<float>(Width)/ZoomLevel);\n    DWORD zoomHeight = static_cast<DWORD> (static_cast<float>(Height)/ZoomLevel);\n    if( g_PenWidth < 5 && zoomWidth > g_PenWidth * 100 && zoomHeight > g_PenWidth * 100 ) {\n\n        return TRUE;\n\n    } else {\n\n        return FALSE;\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// InvalidateCursorMoveArea\n//\n//----------------------------------------------------------------------------\nvoid InvalidateCursorMoveArea( HWND hWnd, float zoomLevel, int width, int height, \n                              POINT currentPt, POINT prevPt, POINT cursorPos )\n{\n    int\t\tx, y;\n    RECT\trc;\n    int\t\tinvWidth = g_PenWidth;\n\n    if( DrawHighlightedCursor( zoomLevel, width, height ) ) {\n        \n        invWidth = g_PenWidth * 3 + 1;\n    }\n    GetZoomedTopLeftCoordinates( zoomLevel, &cursorPos, &x, width, &y, height );\n    rc.left = static_cast<int>(max( 0, (int) ((min( prevPt.x, currentPt.x)-invWidth - x) * zoomLevel)));\n    rc.right = static_cast<int>((max( prevPt.x, currentPt.x)+invWidth - x) * zoomLevel);\n    rc.top = static_cast<int>(max( 0, (int) ((min( prevPt.y, currentPt.y)-invWidth - y) * zoomLevel)));\n    rc.bottom = static_cast<int>((max( prevPt.y, currentPt.y)+invWidth -y) * zoomLevel);\n    InvalidateRect( hWnd, &rc, FALSE );\n\n    OutputDebug( L\"INVALIDATE: (%d, %d) - (%d, %d)\\n\", rc.left, rc.top, rc.right, rc.bottom);\n}\n\n\n//----------------------------------------------------------------------------\n//\n// SavCursorArea\n//\n//----------------------------------------------------------------------------\nvoid SaveCursorArea( HDC hDcTarget, HDC hDcSource, POINT pt )\n{\n    OutputDebug( L\"SaveCursorArea\\n\");\n    int penWidth = g_PenWidth + 2;\n    BitBlt( hDcTarget, 0, 0, penWidth +CURSOR_ARM_LENGTH*2, penWidth +CURSOR_ARM_LENGTH*2,\n        hDcSource, static_cast<INT> (pt.x- penWidth /2)-CURSOR_ARM_LENGTH,\n        static_cast<INT>(pt.y- penWidth /2)-CURSOR_ARM_LENGTH, SRCCOPY|CAPTUREBLT );\n}\n\n//----------------------------------------------------------------------------\n//\n// RestoreCursorArea\n//\n//----------------------------------------------------------------------------\nvoid RestoreCursorArea( HDC hDcTarget, HDC hDcSource, POINT pt )\n{\n    OutputDebug( L\"RestoreCursorArea\\n\");\n    int penWidth = g_PenWidth + 2;\n    BitBlt( hDcTarget, static_cast<INT>(pt.x- penWidth /2)-CURSOR_ARM_LENGTH,\n        static_cast<INT>(pt.y- penWidth /2)-CURSOR_ARM_LENGTH, penWidth +CURSOR_ARM_LENGTH*2,\n        penWidth + CURSOR_ARM_LENGTH*2, hDcSource, 0, 0, SRCCOPY|CAPTUREBLT );\n}\n\n\n//----------------------------------------------------------------------------\n//\n// DrawCursor\n//\n//----------------------------------------------------------------------------\nvoid DrawCursor( HDC hDcTarget, POINT pt, float ZoomLevel, int Width, int Height )\n{\n    RECT\trc;\n\n    if( g_DrawPointer ) {\n\n        Gdiplus::Graphics\tdstGraphics(hDcTarget);\n        if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n        {\n            dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n        }\n        Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n        Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n\n        rc.left = pt.x - CURSOR_ARM_LENGTH;\n        rc.right = pt.x + CURSOR_ARM_LENGTH;\n        rc.top = pt.y - CURSOR_ARM_LENGTH;\n        rc.bottom = pt.y + CURSOR_ARM_LENGTH;\n\n        Gdiplus::GraphicsPath path;\n        path.StartFigure();\n        path.AddLine(static_cast<INT>(rc.left) - 1, static_cast<INT>(rc.top) - 1, static_cast<INT>(rc.right), static_cast<INT>(rc.bottom));\n        path.AddLine(static_cast<INT>(rc.left) - 2, static_cast<INT>(rc.top) - 1, rc.left + (rc.right - rc.left) / 2, rc.top - 1);\n        path.AddLine(static_cast<INT>(rc.left) - 1, static_cast<INT>(rc.top) - 2, rc.left - 1, rc.top + (rc.bottom - rc.top) / 2);\n        path.AddLine(static_cast<INT>(rc.left) - 1, static_cast<INT>(rc.top) - 2, rc.left - 1, rc.top + (rc.bottom - rc.top) / 2);\n        path.AddLine(static_cast<INT>(rc.left + (rc.right - rc.left) / 2), rc.top - 1, rc.left - 1, rc.top + (rc.bottom - rc.top) / 2);\n        pen.SetLineJoin(Gdiplus::LineJoinRound);\n        dstGraphics.DrawPath(&pen, &path);\n        OutputDebug(L\"DrawPointer: %d %d %d %d\\n\", rc.left, rc.top, rc.right, rc.bottom);\n\n    } else if( DrawHighlightedCursor( ZoomLevel, Width, Height )) {\n\n        OutputDebug(L\"DrawHighlightedCursor: %d %d %d %d\\n\", pt.x, pt.y, g_PenWidth, g_PenWidth);\n        Gdiplus::Graphics\tdstGraphics(hDcTarget);\n        if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n        {\n            dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n        }\n        Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n        Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n        Gdiplus::GraphicsPath path;\n        path.StartFigure();\n        pen.SetLineJoin(Gdiplus::LineJoinRound);\n        path.AddLine(static_cast<INT>(pt.x - CURSOR_ARM_LENGTH), pt.y, pt.x + CURSOR_ARM_LENGTH, pt.y);\n        path.CloseFigure();\n        path.StartFigure();\n        pen.SetLineJoin(Gdiplus::LineJoinRound);\n        path.AddLine(static_cast<INT>(pt.x), pt.y - CURSOR_ARM_LENGTH, pt.x, pt.y + CURSOR_ARM_LENGTH);\n        path.CloseFigure();\n        dstGraphics.DrawPath(&pen, &path);\n\n    } else {\n\n        Gdiplus::Graphics\tdstGraphics(hDcTarget);\n        {\n            if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n            {\n                dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n            }\n            Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n\n            Gdiplus::SolidBrush solidBrush(color);\n\n            dstGraphics.FillEllipse(&solidBrush, static_cast<INT>(pt.x-g_PenWidth/2), static_cast<INT>(pt.y-g_PenWidth/2),\n                        static_cast<INT>(g_PenWidth), static_cast<INT>(g_PenWidth));\n        }\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// ResizePen\n//\n//----------------------------------------------------------------------------\nvoid ResizePen( HWND hWnd, HDC hdcScreenCompat, HDC hdcScreenCursorCompat, POINT prevPt,\n                BOOLEAN g_Tracing, BOOLEAN *g_Drawing, float g_LiveZoomLevel, \n                BOOLEAN isUser, int newWidth )\n{\n    if( !g_Tracing ) {\n\n        RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n    }\n\n    OutputDebug( L\"RESIZE_PEN-PRE: penWidth: %d \", g_PenWidth );\n    int prevWidth = g_PenWidth;\n    if( g_ZoomOnLiveZoom )\n    {\n        if( isUser )\n        {\n            // Amplify user delta proportional to LiveZoomLevel\n            newWidth = g_PenWidth + static_cast<int> ((newWidth - static_cast<int>(g_PenWidth))*g_LiveZoomLevel);\n        }\n\n        g_PenWidth = min( max( newWidth, MIN_PEN_WIDTH ),\n            min( static_cast<int>(MAX_PEN_WIDTH * g_LiveZoomLevel), MAX_LIVE_PEN_WIDTH ) );\n        g_RootPenWidth = static_cast<int>(g_PenWidth / g_LiveZoomLevel);\n    }\n    else\n    {\n        g_PenWidth = min( max( newWidth, MIN_PEN_WIDTH ), MAX_PEN_WIDTH );\n        g_RootPenWidth = g_PenWidth;\n    }\n\n    if(prevWidth == static_cast<int>(g_PenWidth) ) {\n        // No change\n        return;\n    }\n\n    OutputDebug( L\"newWidth: %d\\nRESIZE_PEN-POST: penWidth: %d\\n\", newWidth, g_PenWidth );\n    reg.WriteRegSettings( RegSettings );\n    SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n    *g_Drawing = FALSE;\n    EnableDisableStickyKeys( TRUE );\n    SendMessage( hWnd, WM_LBUTTONDOWN, -1, MAKELPARAM(prevPt.x, prevPt.y) );\n}\n\n//----------------------------------------------------------------------------\n//\n// IsPenInverted\n//\n//----------------------------------------------------------------------------\nbool IsPenInverted( WPARAM wParam )\n{\n    POINTER_INPUT_TYPE pointerType;\n    POINTER_PEN_INFO penInfo;\n    return\n        pGetPointerType( GET_POINTERID_WPARAM( wParam ), &pointerType ) && ( pointerType == PT_PEN ) &&\n        pGetPointerPenInfo( GET_POINTERID_WPARAM( wParam ), &penInfo ) && ( penInfo.penFlags & PEN_FLAG_INVERTED );\n}\n\n\n//----------------------------------------------------------------------------\n//\n// CaptureScreenshotAsync\n// \n// Captures the specified screen using the capture APIs\n//\n//----------------------------------------------------------------------------\nstd::future<winrt::com_ptr<ID3D11Texture2D>> CaptureScreenshotAsync(winrt::IDirect3DDevice const& device, winrt::GraphicsCaptureItem const& item, winrt::DirectXPixelFormat const& pixelFormat)\n{\n    auto d3dDevice = GetDXGIInterfaceFromObject<ID3D11Device>(device);\n    winrt::com_ptr<ID3D11DeviceContext> d3dContext;\n    d3dDevice->GetImmediateContext(d3dContext.put());\n\n    // Creating our frame pool with CreateFreeThreaded means that we \n    // will be called back from the frame pool's internal worker thread\n    // instead of the thread we are currently on. It also disables the\n    // DispatcherQueue requirement.\n    auto framePool = winrt::Direct3D11CaptureFramePool::CreateFreeThreaded(\n        device,\n        pixelFormat,\n        1,\n        item.Size());\n    auto session = framePool.CreateCaptureSession(item);\n\n    wil::shared_event captureEvent(wil::EventOptions::ManualReset);\n    winrt::Direct3D11CaptureFrame frame{ nullptr };\n    framePool.FrameArrived([&frame, captureEvent](auto& framePool, auto&)\n        {\n            frame = framePool.TryGetNextFrame();\n\n            // Complete the operation\n            captureEvent.SetEvent();\n        });\n\n    session.IsCursorCaptureEnabled( false );\n    session.StartCapture();\n    co_await winrt::resume_on_signal(captureEvent.get());\n\n    // End the capture\n    session.Close();\n    framePool.Close();\n\n    auto texture = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());\n    auto result = util::CopyD3DTexture(d3dDevice, texture, true);\n\n    co_return result;\n}\n\n//----------------------------------------------------------------------------\n//\n// CaptureScreenshot\n// \n// Captures the specified screen using the capture APIs\n//\n//----------------------------------------------------------------------------\nwinrt::com_ptr<ID3D11Texture2D>CaptureScreenshot(winrt::DirectXPixelFormat const& pixelFormat)\n{\n    auto d3dDevice = util::CreateD3D11Device();\n    auto dxgiDevice = d3dDevice.as<IDXGIDevice>();\n    auto device = CreateDirect3DDevice(dxgiDevice.get());\n\n    // Get the active MONITOR capture device\n    HMONITOR hMon = NULL;\n    POINT cursorPos = { 0, 0 };\n    if (pMonitorFromPoint) {\n\n        GetCursorPos(&cursorPos);\n        hMon = pMonitorFromPoint(cursorPos, MONITOR_DEFAULTTONEAREST);\n    }\n\n    auto item = util::CreateCaptureItemForMonitor(hMon);\n\n    auto capture = CaptureScreenshotAsync(device, item, pixelFormat);\n    capture.wait();\n\n    return capture.get();\n}\n\n\n//----------------------------------------------------------------------------\n//\n// CopyD3DTexture\n// \n//----------------------------------------------------------------------------\ninline auto CopyD3DTexture(winrt::com_ptr<ID3D11Device> const& device, \n            winrt::com_ptr<ID3D11Texture2D> const& texture, bool asStagingTexture)\n{\n    winrt::com_ptr<ID3D11DeviceContext> context;\n    device->GetImmediateContext(context.put());\n\n    D3D11_TEXTURE2D_DESC desc = {};\n    texture->GetDesc(&desc);\n    // Clear flags that we don't need\n    desc.Usage = asStagingTexture ? D3D11_USAGE_STAGING : D3D11_USAGE_DEFAULT;\n    desc.BindFlags = asStagingTexture ? 0 : D3D11_BIND_SHADER_RESOURCE;\n    desc.CPUAccessFlags = asStagingTexture ? D3D11_CPU_ACCESS_READ : 0;\n    desc.MiscFlags = 0;\n\n    // Create and fill the texture copy\n    winrt::com_ptr<ID3D11Texture2D> textureCopy;\n    winrt::check_hresult(device->CreateTexture2D(&desc, nullptr, textureCopy.put()));\n    context->CopyResource(textureCopy.get(), texture.get());\n\n    return textureCopy;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// PrepareStagingTexture\n// \n//----------------------------------------------------------------------------\ninline auto PrepareStagingTexture(winrt::com_ptr<ID3D11Device> const& device, \n            winrt::com_ptr<ID3D11Texture2D> const& texture)\n{\n    // If our texture is already set up for staging, then use it.\n    // Otherwise, create a staging texture.\n    D3D11_TEXTURE2D_DESC desc = {};\n    texture->GetDesc(&desc);\n    if (desc.Usage == D3D11_USAGE_STAGING && desc.CPUAccessFlags & D3D11_CPU_ACCESS_READ)\n    {\n        return texture;\n    }\n\n    return CopyD3DTexture(device, texture, true);\n}\n\n//----------------------------------------------------------------------------\n//\n// GetBytesPerPixel\n// \n//----------------------------------------------------------------------------\ninline size_t\nGetBytesPerPixel(DXGI_FORMAT pixelFormat)\n{\n    switch (pixelFormat)\n    {\n    case DXGI_FORMAT_R32G32B32A32_TYPELESS:\n    case DXGI_FORMAT_R32G32B32A32_FLOAT:\n    case DXGI_FORMAT_R32G32B32A32_UINT:\n    case DXGI_FORMAT_R32G32B32A32_SINT:\n        return 16;\n    case DXGI_FORMAT_R32G32B32_TYPELESS:\n    case DXGI_FORMAT_R32G32B32_FLOAT:\n    case DXGI_FORMAT_R32G32B32_UINT:\n    case DXGI_FORMAT_R32G32B32_SINT:\n        return 12;\n    case DXGI_FORMAT_R16G16B16A16_TYPELESS:\n    case DXGI_FORMAT_R16G16B16A16_FLOAT:\n    case DXGI_FORMAT_R16G16B16A16_UNORM:\n    case DXGI_FORMAT_R16G16B16A16_UINT:\n    case DXGI_FORMAT_R16G16B16A16_SNORM:\n    case DXGI_FORMAT_R16G16B16A16_SINT:\n    case DXGI_FORMAT_R32G32_TYPELESS:\n    case DXGI_FORMAT_R32G32_FLOAT:\n    case DXGI_FORMAT_R32G32_UINT:\n    case DXGI_FORMAT_R32G32_SINT:\n    case DXGI_FORMAT_R32G8X24_TYPELESS:\n        return 8;\n    case DXGI_FORMAT_D32_FLOAT_S8X24_UINT:\n    case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS:\n    case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT:\n    case DXGI_FORMAT_R10G10B10A2_TYPELESS:\n    case DXGI_FORMAT_R10G10B10A2_UNORM:\n    case DXGI_FORMAT_R10G10B10A2_UINT:\n    case DXGI_FORMAT_R11G11B10_FLOAT:\n    case DXGI_FORMAT_R8G8B8A8_TYPELESS:\n    case DXGI_FORMAT_R8G8B8A8_UNORM:\n    case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:\n    case DXGI_FORMAT_R8G8B8A8_UINT:\n    case DXGI_FORMAT_R8G8B8A8_SNORM:\n    case DXGI_FORMAT_R8G8B8A8_SINT:\n    case DXGI_FORMAT_R16G16_TYPELESS:\n    case DXGI_FORMAT_R16G16_FLOAT:\n    case DXGI_FORMAT_UNKNOWN:\n    case DXGI_FORMAT_R16G16_UINT:\n    case DXGI_FORMAT_R16G16_SNORM:\n    case DXGI_FORMAT_R16G16_SINT:\n    case DXGI_FORMAT_R32_TYPELESS:\n    case DXGI_FORMAT_D32_FLOAT:\n    case DXGI_FORMAT_R32_FLOAT:\n    case DXGI_FORMAT_R32_UINT:\n    case DXGI_FORMAT_R32_SINT:\n    case DXGI_FORMAT_R24G8_TYPELESS:\n    case DXGI_FORMAT_D24_UNORM_S8_UINT:\n    case DXGI_FORMAT_R24_UNORM_X8_TYPELESS:\n    case DXGI_FORMAT_X24_TYPELESS_G8_UINT:\n    case DXGI_FORMAT_R8G8_B8G8_UNORM:\n    case DXGI_FORMAT_G8R8_G8B8_UNORM:\n    case DXGI_FORMAT_B8G8R8A8_UNORM:\n    case DXGI_FORMAT_B8G8R8X8_UNORM:\n    case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM:\n    case DXGI_FORMAT_B8G8R8A8_TYPELESS:\n    case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB:\n    case DXGI_FORMAT_B8G8R8X8_TYPELESS:\n    case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB:\n        return 4;\n    case DXGI_FORMAT_R8G8_TYPELESS:\n    case DXGI_FORMAT_R8G8_UNORM:\n    case DXGI_FORMAT_R8G8_UINT:\n    case DXGI_FORMAT_R8G8_SNORM:\n    case DXGI_FORMAT_R8G8_SINT:\n    case DXGI_FORMAT_R16_TYPELESS:\n    case DXGI_FORMAT_R16_FLOAT:\n    case DXGI_FORMAT_D16_UNORM:\n    case DXGI_FORMAT_R16_UNORM:\n    case DXGI_FORMAT_R16_UINT:\n    case DXGI_FORMAT_R16_SNORM:\n    case DXGI_FORMAT_R16_SINT:\n    case DXGI_FORMAT_B5G6R5_UNORM:\n    case DXGI_FORMAT_B5G5R5A1_UNORM:\n    case DXGI_FORMAT_B4G4R4A4_UNORM:\n        return 2;\n    case DXGI_FORMAT_R8_TYPELESS:\n    case DXGI_FORMAT_R8_UNORM:\n    case DXGI_FORMAT_R8_UINT:\n    case DXGI_FORMAT_R8_SNORM:\n    case DXGI_FORMAT_R8_SINT:\n    case DXGI_FORMAT_A8_UNORM:\n        return 1;\n    default:\n        throw winrt::hresult_invalid_argument(L\"Invalid pixel format!\");\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// CopyBytesFromTexture\n// \n//----------------------------------------------------------------------------\ninline auto CopyBytesFromTexture(winrt::com_ptr<ID3D11Texture2D> const& texture, uint32_t subresource = 0)\n{\n    winrt::com_ptr<ID3D11Device> device;\n    texture->GetDevice(device.put());\n    winrt::com_ptr<ID3D11DeviceContext> context;\n    device->GetImmediateContext(context.put());\n\n    auto stagingTexture = PrepareStagingTexture(device, texture);\n\n    D3D11_TEXTURE2D_DESC desc = {};\n    stagingTexture->GetDesc(&desc);\n    auto bytesPerPixel = GetBytesPerPixel(desc.Format);\n\n    // Copy the bits\n    D3D11_MAPPED_SUBRESOURCE mapped = {};\n    winrt::check_hresult(context->Map(stagingTexture.get(), subresource, D3D11_MAP_READ, 0, &mapped));\n\n    auto bytesStride = static_cast<size_t>(desc.Width) * bytesPerPixel;\n    std::vector<byte> bytes(bytesStride * static_cast<size_t>(desc.Height), 0);\n    auto source = static_cast<byte*>(mapped.pData);\n    auto dest = bytes.data();\n    for (auto i = 0; i < static_cast<int>(desc.Height); i++)\n    {\n        memcpy(dest, source, bytesStride);\n\n        source += mapped.RowPitch;\n        dest += bytesStride;\n    }\n    context->Unmap(stagingTexture.get(), 0);\n\n    return bytes;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// StopRecording\n//\n//----------------------------------------------------------------------------\nvoid StopRecording()\n{\n    if( g_RecordToggle == TRUE ) {\n\n        g_SelectRectangle.Stop();\n\n        if ( g_RecordingSession != nullptr ) {\n\n            g_RecordingSession->Close();\n            g_RecordingSession = nullptr;\n        }\n\n        g_RecordToggle = FALSE;\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n\n        if( g_hWndLiveZoom != NULL && g_LiveZoomLevelOne ) {\n\n            if( IsWindowVisible( g_hWndLiveZoom ) ) {\n\n                ShowWindow( g_hWndLiveZoom, SW_HIDE );\n                DestroyWindow( g_hWndLiveZoom );\n                g_LiveZoomLevelOne = false;\n            }\n        }\n#endif\n    }\n}\n\n\n//----------------------------------------------------------------------------\n//\n// GetUniqueRecordingFilename\n//\n// Gets a unique file name for recording saves, using the \" (N)\" suffix\n// approach so that the user can hit OK without worrying about overwriting\n// if they are making multiple recordings in one session or don't want to\n// always see an overwrite dialog or stop to clean up files.\n//\n//----------------------------------------------------------------------------\nauto GetUniqueRecordingFilename()\n{\n    std::filesystem::path path{ g_RecordingSaveLocation };\n\n    // Chop off index if it's there\n    auto base = std::regex_replace( path.stem().wstring(), std::wregex( L\" [(][0-9]+[)]$\" ), L\"\" );\n    path.replace_filename( base + path.extension().wstring() );\n\n    for( int index = 1; std::filesystem::exists( path ); index++ )\n    {\n\n        // File exists, so increment number to avoid collision\n        path.replace_filename( base + L\" (\" + std::to_wstring(index) + L')' + path.extension().wstring() );\n    }\n    return path.stem().wstring() + path.extension().wstring();\n}\n\n//----------------------------------------------------------------------------\n//\n// StartRecordingAsync\n// \n// Starts the screen recording.\n//\n//----------------------------------------------------------------------------\nwinrt::fire_and_forget StartRecordingAsync( HWND hWnd, LPRECT rcCrop, HWND hWndRecord ) try\n{\n    auto tempFolderPath = std::filesystem::temp_directory_path().wstring();\n    auto tempFolder = co_await winrt::StorageFolder::GetFolderFromPathAsync( tempFolderPath );\n    auto appFolder = co_await tempFolder.CreateFolderAsync( L\"ZoomIt\", winrt::CreationCollisionOption::OpenIfExists );\n    auto file = co_await appFolder.CreateFileAsync( L\"zoomit.mp4\", winrt::CreationCollisionOption::ReplaceExisting );\n\n    // Get the device\n    auto d3dDevice = util::CreateD3D11Device();\n    auto dxgiDevice = d3dDevice.as<IDXGIDevice>();\n    g_RecordDevice = CreateDirect3DDevice( dxgiDevice.get() );\n\n    // Get the active MONITOR capture device\n    HMONITOR hMon = NULL;\n    POINT cursorPos = { 0, 0 }; \n    if( pMonitorFromPoint )\t{\n\n        GetCursorPos( &cursorPos );\n        hMon = pMonitorFromPoint( cursorPos, MONITOR_DEFAULTTONEAREST );\n    }\n\n    winrt::Windows::Graphics::Capture::GraphicsCaptureItem item{ nullptr };\n    if( hWndRecord ) \n        item = util::CreateCaptureItemForWindow( hWndRecord );\n    else\n        item = util::CreateCaptureItemForMonitor( hMon );\n\n    auto stream = co_await file.OpenAsync( winrt::FileAccessMode::ReadWrite );\n    g_RecordingSession = VideoRecordingSession::Create(\n                                    g_RecordDevice,\n                                    item,\n                                    *rcCrop,\n                                    g_RecordFrameRate,\n                                    g_CaptureAudio, \n                                    stream );\n\n    if( g_hWndLiveZoom != NULL )\n        g_RecordingSession->EnableCursorCapture( false );\n\n    co_await g_RecordingSession->StartAsync();\n\n    // g_RecordingSession isn't null if we're aborting a recording\n    if( g_RecordingSession == nullptr ) {\n\n        g_bSaveInProgress = true;\n\n        SendMessage( g_hWndMain, WM_USER_SAVE_CURSOR, 0, 0 );\n\n        winrt::StorageFile destFile = nullptr;\n        HRESULT hr = S_OK;\n        try {\n            auto saveDialog = wil::CoCreateInstance<IFileSaveDialog>( CLSID_FileSaveDialog );\n            FILEOPENDIALOGOPTIONS options;\n            if( SUCCEEDED( saveDialog->GetOptions( &options ) ) )\n                saveDialog->SetOptions( options | FOS_FORCEFILESYSTEM );\n            wil::com_ptr<IShellItem> videosItem;\n            if( SUCCEEDED ( SHGetKnownFolderItem( FOLDERID_Videos, KF_FLAG_DEFAULT, nullptr, IID_IShellItem, (void**) videosItem.put() ) ) )\n                saveDialog->SetDefaultFolder( videosItem.get() );\n            saveDialog->SetDefaultExtension( L\".mp4\" );\n            COMDLG_FILTERSPEC fileTypes[] = {\n                { L\"MP4 视频\", L\"*.mp4\" }\n            };\n            saveDialog->SetFileTypes( _countof( fileTypes ), fileTypes );\n\n            if( g_RecordingSaveLocation.size() == 0) {\n\n                wil::com_ptr<IShellItem> shellItem;\n                wil::unique_cotaskmem_string folderPath;\n                if (SUCCEEDED(saveDialog->GetFolder(shellItem.put())) && SUCCEEDED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, folderPath.put())))\n                    g_RecordingSaveLocation = folderPath.get();\n                g_RecordingSaveLocation = std::filesystem::path{ g_RecordingSaveLocation } /= DEFAULT_RECORDING_FILE;\n            }\n            auto suggestedName = GetUniqueRecordingFilename();\n            saveDialog->SetFileName( suggestedName.c_str() );\n\n            THROW_IF_FAILED( saveDialog->Show( hWnd ) );\n            wil::com_ptr<IShellItem> shellItem;\n            THROW_IF_FAILED(saveDialog->GetResult(shellItem.put()));\n            wil::unique_cotaskmem_string filePath;\n            THROW_IF_FAILED(shellItem->GetDisplayName(SIGDN_FILESYSPATH, filePath.put()));\n            auto path = std::filesystem::path( filePath.get() );\n\n            winrt::StorageFolder folder{ co_await winrt::StorageFolder::GetFolderFromPathAsync( path.parent_path().c_str() ) };\n            destFile = co_await folder.CreateFileAsync( path.filename().c_str(), winrt::CreationCollisionOption::ReplaceExisting );\n        }\n        catch( const wil::ResultException& error ) {\n\n            hr = error.GetErrorCode();\n        }\n        if( destFile == nullptr ) {\n\n            co_await file.DeleteAsync();\n        }\n        else {\n\n            co_await file.MoveAndReplaceAsync( destFile );\n            g_RecordingSaveLocation = file.Path();\n            SaveToClipboard(g_RecordingSaveLocation.c_str(), hWnd);\n        }\n        g_bSaveInProgress = false;\n\n        SendMessage( g_hWndMain, WM_USER_RESTORE_CURSOR, 0, 0 );\n        if( hWnd == g_hWndMain )\n            RestoreForeground();\n\n        if( FAILED( hr ) )\n            throw winrt::hresult_error( hr );\n    }\n    else {\n\n        co_await file.DeleteAsync();\n        g_RecordingSession = nullptr;\n    }\n} catch( const winrt::hresult_error& error ) {\n\n    PostMessage( g_hWndMain, WM_USER_STOP_RECORDING, 0, 0 );\n\n    // Suppress the error from canceling the save dialog\n    if( error.code() == HRESULT_FROM_WIN32( ERROR_CANCELLED ))\n        co_return;\n\n    if (g_RecordToggle == FALSE) {\n\n        MessageBox(g_hWndMain, L\"录屏还没开始，已取消\", APPNAME, MB_OK | MB_ICONERROR | MB_SYSTEMMODAL);\n    }\n    else {\n\n        ErrorDialogString(g_hWndMain, L\"无法开始录屏\", error.message().c_str());\n    }\n}\n\n//----------------------------------------------------------------------------\n//\n// UpdateMonitorInfo\n//\n//----------------------------------------------------------------------------\nvoid UpdateMonitorInfo( POINT point, MONITORINFO* monInfo )\n{\n    HMONITOR hMon{};\n    if( pMonitorFromPoint != nullptr )\n    {\n        hMon = pMonitorFromPoint( point, MONITOR_DEFAULTTONEAREST );\n    }\n    if( hMon != nullptr )\n    {\n        monInfo->cbSize = sizeof *monInfo;\n        pGetMonitorInfo( hMon, monInfo );\n    }\n    else\n    {\n        *monInfo = {};\n        HDC hdcScreen = CreateDC( L\"DISPLAY\", nullptr, nullptr, nullptr );\n        if( hdcScreen != nullptr )\n        {\n            monInfo->rcMonitor.right = GetDeviceCaps( hdcScreen, HORZRES );\n            monInfo->rcMonitor.bottom = GetDeviceCaps( hdcScreen, VERTRES );\n            DeleteDC( hdcScreen );\n        }\n    }\n}\n\n#ifdef __ZOOMIT_POWERTOYS__\nHRESULT OpenPowerToysSettingsApp()\n{\n    std::wstring path = get_module_folderpath(g_hInstance);\n    path += L\"\\\\PowerToys.exe\";\n\n    std::wstring openSettings = L\"--open-settings=ZoomIt\";\n\n    std::wstring full_command_path = path + L\" \" + openSettings;\n\n    STARTUPINFO startupInfo;\n    ZeroMemory(&startupInfo, sizeof(STARTUPINFO));\n    startupInfo.cb = sizeof(STARTUPINFO);\n    startupInfo.wShowWindow = SW_SHOWNORMAL;\n\n    PROCESS_INFORMATION processInformation;\n\n    CreateProcess(\n        path.c_str(),\n        full_command_path.data(),\n        NULL,\n        NULL,\n        TRUE,\n        0,\n        NULL,\n        NULL,\n        &startupInfo,\n        &processInformation);\n\n    if (!CloseHandle(processInformation.hProcess))\n    {\n        return HRESULT_FROM_WIN32(GetLastError());\n    }\n    if (!CloseHandle(processInformation.hThread))\n    {\n        return HRESULT_FROM_WIN32(GetLastError());\n    }\n    return S_OK;\n}\n#endif // __ZOOMIT_POWERTOYS__\n\n//----------------------------------------------------------------------------\n//\n// ShowMainWindow\n//\n//----------------------------------------------------------------------------\nvoid ShowMainWindow(HWND hWnd, const MONITORINFO& monInfo, int width, int height)\n{\n    // Show the window first\n    SetWindowPos(hWnd, HWND_TOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top,\n        width, height, SWP_SHOWWINDOW | SWP_NOCOPYBITS);\n\n    // Now invalidate and update the window\n    InvalidateRect(hWnd, NULL, TRUE);\n    UpdateWindow(hWnd);\n\n    SetForegroundWindow(hWnd);\n    SetActiveWindow(hWnd);\n}\n\n//----------------------------------------------------------------------------\n//\n// MainWndProc\n//\n//----------------------------------------------------------------------------\nLRESULT APIENTRY MainWndProc(\n    HWND hWnd,     \n    UINT message,\n    WPARAM wParam, \n    LPARAM lParam)\n{\n    static int\t\twidth, height;\n    static HDC\t\thdcScreen, hdcScreenCompat, hdcScreenCursorCompat, hdcScreenSaveCompat;\n    static HBITMAP\thbmpCompat, hbmpDrawingCompat, hbmpCursorCompat;\n    static RECT     cropRc{};\n    static BITMAP\tbmp;\n    static BOOLEAN\tg_TimerActive = FALSE;\n    static BOOLEAN\tg_Zoomed = FALSE;\n    static TypeModeState g_TypeMode = TypeModeOff;\n    static BOOLEAN\tg_HaveTyped = FALSE;\n    static DEVMODE\tsecondaryDevMode;\n    static RECT\t\tg_LiveZoomSourceRect;\n    static float\tg_LiveZoomLevel;\n    static float\tzoomLevel;\n    static float\tzoomTelescopeStep;\n    static float\tzoomTelescopeTarget;\n    static POINT\tcursorPos;\n    static POINT\tsavedCursorPos;\n    static RECT\t\tcursorRc;\n    static RECT\t\tboundRc;\n    static POINT\tprevPt;\n    static POINT\ttextStartPt;\n    static POINT\ttextPt;\n    static P_DRAW_UNDO drawUndoList = NULL;\n    static P_TYPED_KEY\ttypedKeyList = NULL;\n    static BOOLEAN\tg_HaveDrawn = FALSE;\n    static DWORD\tg_DrawingShape = 0;\n    static DWORD    prevPenWidth = g_PenWidth;\n    static POINT\tg_RectangleAnchor;\n    static RECT\t\tg_rcRectangle;\n    static BOOLEAN\tg_Tracing = FALSE;\n    static int\t\tg_BlankedScreen = 0;\n    static int\t\tg_StraightDirection = 0;\n    static BOOLEAN\tg_Drawing = FALSE;\n    static HWND\t\tg_ActiveWindow = NULL;\n    static int\t\tbreakTimeout;\n    static HBITMAP\tg_hBackgroundBmp = NULL;\n    static HDC\t\tg_hDcBackgroundFile;\n    static HPEN\t\thDrawingPen;\n    static HFONT\thTimerFont;\n    static HFONT\thNegativeTimerFont;\n    static HFONT\thTypingFont;\n    static MONITORINFO\tmonInfo;\n    static MONITORINFO  lastMonInfo;\n    static HWND\t\thTargetWindow = NULL;\n    static RECT\t\trcTargetWindow;\n    static BOOLEAN  forcePenResize = TRUE;\n    static BOOLEAN  activeBreakShowDesktop = g_BreakShowDesktop;\n    static BOOLEAN\tactiveBreakShowBackgroundFile = g_BreakShowBackgroundFile;\n    static TCHAR    activeBreakBackgroundFile[MAX_PATH] = {0};\n    static UINT     wmTaskbarCreated;\n#if 0\n    TITLEBARINFO\ttitleBarInfo;\n    WINDOWINFO\t\ttargetWindowInfo;\n#endif\n    bool\t\t\tisCaptureSupported = false;\n    RECT\t\t\trc, rc1;\n    PAINTSTRUCT\t\tps; \n    TCHAR\t\t\ttimerText[16];\n    TCHAR\t\t\tnegativeTimerText[16];\n    BOOLEAN\t\t\tpenInverted;\n    BOOLEAN\t\t\tzoomIn;\n    HDC\t\t\t\thDc;\n    HWND\t\t\thWndRecord;\n    int\t\t\t\tx, y, delta;\n    HMENU\t\t\thPopupMenu;\n    OPENFILENAME\topenFileName;\n    static TCHAR\tfilePath[MAX_PATH] = {L\"zoomit\"};\n    NOTIFYICONDATA\ttNotifyIconData;\n\n    const auto drawAllRightJustifiedLines = [&rc]( long lineHeight, bool doPop = false ) {\n        rc.top = textPt.y - static_cast<LONG>(g_TextBufferPreviousLines.size()) * lineHeight;\n\n        for( const auto& line : g_TextBufferPreviousLines )\n        {\n            DrawText( hdcScreenCompat, line.c_str(), static_cast<int>(line.length()), &rc, DT_CALCRECT );\n            const auto textWidth = rc.right - rc.left;\n            rc.left = textPt.x - textWidth;\n            rc.right = textPt.x;\n            DrawText( hdcScreenCompat, line.c_str(), static_cast<int>(line.length()), &rc, DT_LEFT );\n            rc.top += lineHeight;\n        }\n        if( !g_TextBuffer.empty() )\n        {\n            if( doPop )\n            {\n                g_TextBuffer.pop_back();\n            }\n            DrawText( hdcScreenCompat, g_TextBuffer.c_str(), static_cast<int>(g_TextBuffer.length()), &rc, DT_CALCRECT );\n            rc.left = textPt.x - (rc.right - rc.left);\n            rc.right = textPt.x;\n            DrawText( hdcScreenCompat, g_TextBuffer.c_str(), static_cast<int>(g_TextBuffer.length()), &rc, DT_LEFT );\n        }\n    };\n\n    switch (message) {\n    case WM_CREATE:\n\n        // get default font\n        GetObject( GetStockObject(DEFAULT_GUI_FONT), sizeof g_LogFont, &g_LogFont ); \n        g_LogFont.lfWeight = FW_NORMAL;\n        hDc = CreateCompatibleDC( NULL );\n        g_LogFont.lfHeight = -MulDiv(8, GetDeviceCaps(hDc, LOGPIXELSY), 72);\n        DeleteDC( hDc );\n\n        reg.ReadRegSettings( RegSettings );\n        \n        // to support migrating from \n        if ((g_PenColor >> 24) == 0) {\n            g_PenColor |= 0xFF << 24;\n        }\n\n        g_PenWidth = g_RootPenWidth;\n\n        g_ToggleMod = GetKeyMod( g_ToggleKey );\n        g_LiveZoomToggleMod = GetKeyMod( g_LiveZoomToggleKey );\n        g_DrawToggleMod = GetKeyMod( g_DrawToggleKey );\n        g_BreakToggleMod = GetKeyMod( g_BreakToggleKey );\n        g_DemoTypeToggleMod = GetKeyMod( g_DemoTypeToggleKey );\n        g_SnipToggleMod = GetKeyMod( g_SnipToggleKey );\n        g_RecordToggleMod = GetKeyMod( g_RecordToggleKey );\n\n        if( !g_OptionsShown && !g_StartedByPowerToys ) {\n            // First run should show options when running as standalone. If not running as standalone,\n            // options screen won't show and we should register keys instead.\n            SendMessage( hWnd, WM_COMMAND, IDC_OPTIONS, 0 );\n            g_OptionsShown = TRUE;\n            reg.WriteRegSettings( RegSettings );\n        } else {\n            BOOL\tshowOptions = FALSE;\n\n            if( g_ToggleKey && !RegisterHotKey( hWnd, ZOOM_HOTKEY, g_ToggleMod, g_ToggleKey & 0xFF)) {\n\n                MessageBox( hWnd, L\"此快捷键已被占用。\\n请重新选择放大快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                showOptions = TRUE;\n\n            } else if( g_LiveZoomToggleKey && \n                (!RegisterHotKey( hWnd, LIVE_HOTKEY, g_LiveZoomToggleMod, g_LiveZoomToggleKey & 0xFF) ||\n                    !RegisterHotKey(hWnd, LIVE_DRAW_HOTKEY, (g_LiveZoomToggleMod ^ MOD_SHIFT), g_LiveZoomToggleKey & 0xFF))) {\n\n                MessageBox( hWnd, L\"此快捷键已被占用。\\n请重新选择实时放大快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                showOptions = TRUE;\n\n            } else if( g_DrawToggleKey && !RegisterHotKey( hWnd, DRAW_HOTKEY, g_DrawToggleMod, g_DrawToggleKey & 0xFF )) {\n\n                MessageBox( hWnd, L\"此快捷键已被占用。\\n请重新选择画图快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                showOptions = TRUE;\n\n            }\n            else if (g_BreakToggleKey && !RegisterHotKey(hWnd, BREAK_HOTKEY, g_BreakToggleMod, g_BreakToggleKey & 0xFF)) {\n\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择倒计时快捷键。\",\n                    APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n\n            }\n            else if( g_DemoTypeToggleKey && \n                (!RegisterHotKey( hWnd, DEMOTYPE_HOTKEY, g_DemoTypeToggleMod, g_DemoTypeToggleKey & 0xFF ) ||\n                 !RegisterHotKey(hWnd, DEMOTYPE_RESET_HOTKEY, (g_DemoTypeToggleMod ^ MOD_SHIFT), g_DemoTypeToggleKey & 0xFF))) {\n\n                MessageBox( hWnd, L\"此快捷键已被占用。\\n请重新选择自动打字快捷键。\",\n                    APPNAME, MB_ICONERROR );\n                showOptions = TRUE;\n\n            }\n            else if (g_SnipToggleKey && \n                (!RegisterHotKey(hWnd, SNIP_HOTKEY, g_SnipToggleMod, g_SnipToggleKey & 0xFF) ||\n                 !RegisterHotKey(hWnd, SNIP_SAVE_HOTKEY, (g_SnipToggleMod ^ MOD_SHIFT), g_SnipToggleKey & 0xFF))) {\n\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择截图快捷键。\",\n                    APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n\n            }\n            else if (g_RecordToggleKey && \n                (!RegisterHotKey(hWnd, RECORD_HOTKEY, g_RecordToggleMod | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) ||\n                 !RegisterHotKey(hWnd, RECORD_CROP_HOTKEY, (g_RecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) ||\n                 !RegisterHotKey(hWnd, RECORD_WINDOW_HOTKEY, (g_RecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF))) {\n\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择录屏快捷键。\",\n                    APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n            if( showOptions ) {\n\n                SendMessage( hWnd, WM_COMMAND, IDC_OPTIONS, 0 );\n            }\n        }\n        SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );\n        wmTaskbarCreated = RegisterWindowMessage(_T(\"TaskbarCreated\"));\n        return TRUE;\n\n    case WM_CLOSE:\n        // Do not allow users to close the main window, for example with Alt-F4.\n        return 0;\n\n    case WM_HOTKEY:\n        if( g_RecordCropping == TRUE )\n        {\n            if( wParam != RECORD_CROP_HOTKEY )\n            {\n                // Cancel cropping on any hotkey.\n                g_SelectRectangle.Stop();\n                g_RecordCropping = FALSE;\n\n                // Cropping is handled by a blocking call in WM_HOTKEY, so post\n                // this message to the window for processing after the previous\n                // WM_HOTKEY message completes processing.\n                PostMessage( hWnd, message, wParam, lParam );\n            }\n            return 0;\n        }\n\n        //\n        // Magic value that comes from tray context menu\n        //\n        if (lParam == 1) {\n\n            //\n            // Sleep to let context menu dismiss\n            //\n            Sleep(250);\n        }\n        switch( wParam ) {\n        case LIVE_DRAW_HOTKEY:\n        {\n            OutputDebug(L\"LIVE_DRAW_HOTKEY\\n\");\n            LONG_PTR exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);\n\n            if ((exStyle & WS_EX_LAYERED)) {\n                OutputDebug(L\"LiveDraw reactivate\\n\");\n\n                // Just focus on the window and re-enter drawing mode\n                SetFocus(hWnd);\n                SetForegroundWindow(hWnd);\n                SendMessage(hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(cursorPos.x, cursorPos.y));\n                SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(cursorPos.x, cursorPos.y));\n                if( IsWindowVisible( g_hWndLiveZoom ) )\n                {\n                    SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 );\n                }\n                break;\n            }\n            else {\n                OutputDebug(L\"LiveDraw create\\n\");\n\n                exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);\n                SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle | WS_EX_LAYERED);\n                SetLayeredWindowAttributes(hWnd, COLORREF(RGB(0, 0, 0)), 0, LWA_COLORKEY);\n                pMagSetWindowFilterList( g_hWndLiveZoomMag, MW_FILTERMODE_EXCLUDE, 0, nullptr );\n            }\n            [[fallthrough]];\n        }\n        case DRAW_HOTKEY:\n            //\n            // Enter drawing mode without zoom\n            //\n#ifdef __ZOOMIT_POWERTOYS__\n            if( g_StartedByPowerToys )\n            {\n                Trace::ZoomItActivateDraw();\n            }\n#endif // __ZOOMIT_POWERTOYS__\n\n            if( !g_Zoomed ) {\n                OutputDebug(L\"LiveDraw: %d (%d)\\n\", wParam, (wParam == LIVE_DRAW_HOTKEY));\n\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n                if( IsWindowVisible( g_hWndLiveZoom ) && !g_LiveZoomLevelOne ) {\n#else\n                if( IsWindowVisible( g_hWndLiveZoom )) {\n#endif\n\n                    OutputDebug(L\"   In Live zoom\\n\");\n                    SendMessage(hWnd, WM_HOTKEY, ZOOM_HOTKEY, wParam == LIVE_DRAW_HOTKEY ? LIVE_DRAW_ZOOM : 0);\n\n                } else {\n                    OutputDebug(L\"   Not in Live zoom\\n\");\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, wParam == LIVE_DRAW_HOTKEY ? LIVE_DRAW_ZOOM : 0 );\n                    zoomLevel = zoomTelescopeTarget = 1;\n                    SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y ));\n                }\n                if(wParam == LIVE_DRAW_HOTKEY) {\n\n                    SetLayeredWindowAttributes(hWnd, COLORREF(RGB(0, 0, 0)), 0, LWA_COLORKEY);\n                    SendMessage(hWnd, WM_KEYDOWN, 'K', LIVE_DRAW_ZOOM);\n                    SetTimer(hWnd, 3, 10, NULL);\n                    SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(cursorPos.x, cursorPos.y));\n                    ShowMainWindow(hWnd, monInfo, width, height);\n                    if( ( g_PenColor & 0xFFFFFF ) == COLOR_BLUR )\n                    {\n                        // Blur is not supported in LiveDraw\n                        g_PenColor = COLOR_RED;\n                    }\n                    // Highlight is not supported in LiveDraw\n                    g_PenColor |= 0xFF << 24;\n\t\t\t\t}\n            } \n            break;\n\n        case SNIP_SAVE_HOTKEY:\n        case SNIP_HOTKEY:\n        {\n            // Block liveZoom liveDraw snip due to mirroring bug\n            if( IsWindowVisible( g_hWndLiveZoom )\n                && ( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) )\n            {\n                break;\n            }\n\n            bool zoomed = true;\n#ifdef __ZOOMIT_POWERTOYS__\n            if( g_StartedByPowerToys )\n            {\n                Trace::ZoomItActivateSnip();\n            }\n#endif // __ZOOMIT_POWERTOYS__\n\n            // First, static zoom\n            if( !g_Zoomed )\n            {\n                zoomed = false;\n                if( IsWindowVisible( g_hWndLiveZoom ) && !g_LiveZoomLevelOne )\n                {\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_ZOOM );\n                }\n                else\n                {\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, LIVE_DRAW_ZOOM);\n                }\n                zoomLevel = zoomTelescopeTarget = 1;\n            }\n            else if( g_Drawing )\n            {\n                // Exit drawing mode to hide the drawing cursor\n                SendMessage( hWnd, WM_USER_EXIT_MODE, 0, 0 );\n\n                // Exit again if still in drawing mode, which happens from type mode\n                if( g_Drawing )\n                {\n                    SendMessage( hWnd, WM_USER_EXIT_MODE, 0, 0 );\n                }\n            }\n            ShowMainWindow(hWnd, monInfo, width, height);\n\n            // Now copy crop or copy+save\n            if( LOWORD( wParam ) == SNIP_SAVE_HOTKEY )\n            {\n                SendMessage( hWnd, WM_COMMAND, IDC_SAVE_CROP, ( zoomed ? 0 : SHALLOW_ZOOM ) );\n            }\n            else\n            {\n                SendMessage( hWnd, WM_COMMAND, IDC_COPY_CROP, ( zoomed ? 0 : SHALLOW_ZOOM ) );\n            }\n\n            // Now if we weren't zoomed, unzoom\n            if( !zoomed )\n            {\n                if( g_ZoomOnLiveZoom )\n                {\n                    // hiding the cursor allows for a cleaner transition back to the magnified cursor\n                    ShowCursor( false );\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 );\n                    ShowCursor( true );\n                }\n                else\n                {\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_ZOOM );\n                }\n            }\n\n            // exit zoom\n            if( g_Zoomed )\n            {\n                // If from liveDraw, extra care is needed to destruct\n                if( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED )\n                {\n                    OutputDebug( L\"Exiting liveDraw after snip\\n\" );\n                    SendMessage( hWnd, WM_KEYDOWN, VK_ESCAPE, 0 );\n                }\n                else\n                {\n                    // Set wparam to 1 to exit without animation\n                    OutputDebug(L\"Exiting zoom after snip\\n\" );\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_DESTROY );\n                }\n            }\n            break;\n        }\n\n        case BREAK_HOTKEY:\n            //\n            // Go to break timer\n            //\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n            if( !g_Zoomed && ( !IsWindowVisible( g_hWndLiveZoom ) || g_LiveZoomLevelOne ) ) {\n#else\n            if( !g_Zoomed && !IsWindowVisible( g_hWndLiveZoom )) {\n#endif\n\n                SendMessage( hWnd, WM_COMMAND, IDC_BREAK, 0 );\n            }\n            break;\n\n        case DEMOTYPE_RESET_HOTKEY:\n            ResetDemoTypeIndex();\n            break;\n\n        case DEMOTYPE_HOTKEY:\n        {\n            //\n            // Live type\n            //\n            switch( StartDemoType( g_DemoTypeFile, g_DemoTypeSpeedSlider, g_DemoTypeUserDriven ) )\n            {\n            case ERROR_LOADING_FILE:\n                ErrorDialog( hWnd, L\"加载自动打字文件时出错\", GetLastError() );\n                break;\n\n            case NO_FILE_SPECIFIED:\n                MessageBox( hWnd, L\"未选择自动打字文件\", APPNAME, MB_OK );\n                break;\n\n            case FILE_SIZE_OVERFLOW:\n            {\n                std::wstring msg = L\"自动打字文件过大，最大\"\n                    + std::to_wstring( MAX_INPUT_SIZE ) + L\"字节\";\n                MessageBox( hWnd, msg.c_str(), APPNAME, MB_OK );\n                break;\n            }\n\n            case UNKNOWN_FILE_DATA:\n                MessageBox( hWnd, L\"无法读取自动打字文件（试试保存为 UTF-8 编码）\", APPNAME, MB_OK );\n                break;\n            default:\n#ifdef __ZOOMIT_POWERTOYS__\n                if( g_StartedByPowerToys )\n                {\n                    Trace::ZoomItActivateDemoType();\n                }\n#endif // __ZOOMIT_POWERTOYS__\n                break;\n            }\n            break;\n        }\n\n        case LIVE_HOTKEY:\n            //\n            // Live zoom\n            //\n            OutputDebug(L\"*** LIVE_HOTKEY\\n\");\n\n            // If LiveZoom and LiveDraw are active then exit both\n            if( g_Zoomed && IsWindowVisible( g_hWndLiveZoom ) && ( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) )\n            {\n                SendMessage( hWnd, WM_KEYDOWN, VK_ESCAPE, 0 );\n                PostMessage(hWnd, WM_HOTKEY, LIVE_HOTKEY, 0);\n                break;\n            }\n\n            if( !g_Zoomed && !g_TimerActive && ( !g_fullScreenWorkaround || !g_RecordToggle ) ) {\n#ifdef __ZOOMIT_POWERTOYS__\n                if( g_StartedByPowerToys )\n                {\n                    Trace::ZoomItActivateLiveZoom();\n                }\n#endif // __ZOOMIT_POWERTOYS__\n\n                if( g_hWndLiveZoom == NULL ) {\n                    OutputDebug(L\"Create LIVEZOOM\\n\");\n                    g_hWndLiveZoom = CreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_LAYERED | WS_EX_TRANSPARENT,\n                        L\"MagnifierClass\", L\"演示工具实时放大\", \n                        WS_POPUP | WS_CLIPSIBLINGS,\n                        0, 0, 0, 0, NULL, NULL, g_hInstance, static_cast<PVOID>(GetForegroundWindow()) );\n                    pSetLayeredWindowAttributes( hWnd, 0, 0, LWA_ALPHA );\n                    EnableWindow( g_hWndLiveZoom, FALSE );\n                    pMagSetWindowFilterList( g_hWndLiveZoomMag, MW_FILTERMODE_EXCLUDE, 1, &hWnd );\n\n                } else {\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n                    if( g_LiveZoomLevelOne ) {\n                        OutputDebug(L\"liveZoom level one\\n\");\n                        SendMessage( g_hWndLiveZoom, WM_USER_SET_ZOOM, static_cast<WPARAM>(g_LiveZoomLevel), 0 );\n                    }\n                    else {\n#endif\n\n                    if( IsWindowVisible( g_hWndLiveZoom )) {\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n\n                        if( g_RecordToggle )\n                            g_LiveZoomLevel = g_ZoomLevels[g_SliderZoomLevel];\n#endif\n                        // Unzoom\n                        SendMessage( g_hWndLiveZoom, WM_KEYDOWN, VK_ESCAPE, 0 ); \n\n                    } else {\n                    \n                        OutputDebug(L\"Show liveZoom\\n\");\n                        ShowWindow( g_hWndLiveZoom, SW_SHOW );\n                    }\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n                    }\n#endif\n                }\n\n                if ( g_RecordToggle )\n                {\n                    g_SelectRectangle.UpdateOwner( g_hWndLiveZoom );\n                }\n            }\n            break;\n\n        case RECORD_HOTKEY:\n        case RECORD_CROP_HOTKEY:\n        case RECORD_WINDOW_HOTKEY:\n\n            //\n            // Recording\n            // This gets entered twice per recording:\n            // 1. When the hotkey is pressed to start recording\n            // 2. When the hotkey is pressed to stop recording\n            //\n            if( g_fullScreenWorkaround && g_hWndLiveZoom != NULL && IsWindowVisible( g_hWndLiveZoom ) != FALSE )\n            {\n                break;\n            }\n\n            if( g_RecordCropping == TRUE )\n            {\n                break;\n            } \n\n            // Start screen recording\n            try\n            {\n                isCaptureSupported = winrt::GraphicsCaptureSession::IsSupported();\n            }\n            catch( const winrt::hresult_error& ) {}\n            if( !isCaptureSupported )\n            {\n                MessageBox( hWnd, L\"录屏功能至少需要 Windows 10 2019年5月版本。\", APPNAME, MB_OK );\n                break;\n            }\n\n            // If shift, then we're cropping\n            hWndRecord = 0;\n            if( wParam == RECORD_CROP_HOTKEY )\n            {\n                if( g_RecordToggle == TRUE )\n                {\n                    // Already recording\n                    break;\n                } \n\n                g_RecordCropping = TRUE;\n\n                POINT savedPoint{};\n                RECT savedClip = {};\n\n                // Handle the cursor for live zoom and static zoom modes.\n                if( ( g_hWndLiveZoom != nullptr ) || ( g_Zoomed == TRUE ) )\n                {\n                    GetCursorPos( &savedPoint );\n                    UpdateMonitorInfo( savedPoint, &monInfo );\n                }\n                if( g_hWndLiveZoom != nullptr )\n                {\n                    // Hide the magnified cursor.\n                    SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 );\n\n                    // Show the system cursor where the magnified was.\n                    g_LiveZoomSourceRect = *reinterpret_cast<RECT *>( SendMessage( g_hWndLiveZoom, WM_USER_GET_SOURCE_RECT, 0, 0 ) );\n                    savedPoint = ScalePointInRects( savedPoint, g_LiveZoomSourceRect, monInfo.rcMonitor );\n                    SetCursorPos( savedPoint.x, savedPoint.y );\n                    if ( pMagShowSystemCursor != nullptr )\n                    {\n                        pMagShowSystemCursor( TRUE );\n                    }\n                }\n                else if( ( g_Zoomed == TRUE ) && ( g_Drawing == TRUE ) )\n                {\n                    // Unclip the cursor.\n                    GetClipCursor( &savedClip );\n                    ClipCursor( nullptr );\n\n                    // Scale the cursor position to the zoomed and move it.\n                    auto point = ScalePointInRects( savedPoint, boundRc, monInfo.rcMonitor );\n                    SetCursorPos( point.x, point.y );\n                }\n\n                if( g_Zoomed == FALSE )\n                {\n                    SetWindowPos( hWnd, HWND_TOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top, width, height, SWP_SHOWWINDOW );\n                }\n\n                // This call blocks with a message loop while cropping.\n                auto canceled = !g_SelectRectangle.Start( ( g_hWndLiveZoom != nullptr ) ? g_hWndLiveZoom : hWnd );\n                g_RecordCropping = FALSE;\n\n                // Restore the cursor if applicable.\n                if( g_hWndLiveZoom != nullptr )\n                {\n                    // Hide the system cursor.\n                    if ( pMagShowSystemCursor != nullptr )\n                    {\n                        pMagShowSystemCursor( FALSE );\n                    }\n\n                    // Show the magnified cursor where the system cursor was.\n                    GetCursorPos( &savedPoint );\n                    savedPoint = ScalePointInRects( savedPoint, monInfo.rcMonitor, g_LiveZoomSourceRect );\n                    SetCursorPos( savedPoint.x, savedPoint.y );\n                    SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, TRUE, 0 );\n                }\n                else if( g_Zoomed == TRUE )\n                {\n                    SetCursorPos( savedPoint.x, savedPoint.y );\n\n                    if ( g_Drawing == TRUE )\n                    {\n                        ClipCursor( &savedClip );\n                    }\n                }\n\n                SetForegroundWindow( hWnd );\n                if( g_Zoomed == FALSE )\n                {\n                    SetActiveWindow( hWnd );\n                    ShowWindow( hWnd, SW_HIDE );\n                }\n\n                if( canceled )\n                {\n                    break;\n                }\n\n                g_SelectRectangle.UpdateOwner( ( g_hWndLiveZoom != nullptr ) ? g_hWndLiveZoom : hWnd );\n                cropRc = g_SelectRectangle.SelectedRect();\n            }\n            else\n            {\n                cropRc = {};\n\n                // if we're recording a window, get the window \n                if (wParam == RECORD_WINDOW_HOTKEY)\n                {\n                    GetCursorPos(&cursorPos);\n                    hWndRecord = WindowFromPoint(cursorPos);\n                    while( GetParent(hWndRecord) != NULL)\n                    {\n                        hWndRecord = GetParent(hWndRecord);\n                    }\n                    if( hWndRecord == GetDesktopWindow()) {\n\n                        hWndRecord = NULL;\n                    }\n                }\n            }\n\n            if( g_RecordToggle == FALSE )\n            {\n                g_RecordToggle = TRUE;\n#ifdef __ZOOMIT_POWERTOYS__\n                if( g_StartedByPowerToys )\n                {\n                    Trace::ZoomItActivateRecord();\n                }\n#endif // __ZOOMIT_POWERTOYS__\n\n                StartRecordingAsync( hWnd, &cropRc, hWndRecord );\n            }\n            else\n            {\n                StopRecording();\n            }\n            break;\n\n        case ZOOM_HOTKEY:\n            //\n            // Zoom\n            //\n            // Don't react to hotkey while options are open or we're\n            // saving the screen or live zoom is active\n            //\n            if( hWndOptions ) {\n\n                break;\n            }\n            \n            OutputDebug( L\"ZOOM HOTKEY: %d\\n\", lParam);\n            if( g_TimerActive ) {\n\n                //\n                // Finished with break timer\n                //\n                if( g_BreakOnSecondary )\n                {\n                    EnableDisableSecondaryDisplay( hWnd, FALSE, &secondaryDevMode );\n                }\n\n                if( lParam != SHALLOW_DESTROY )\n                {\n                    ShowWindow( hWnd, SW_HIDE );\n                    if( g_hBackgroundBmp )\n                    {\n                        DeleteObject( g_hBackgroundBmp );\n                        DeleteDC( g_hDcBackgroundFile );\n                        g_hBackgroundBmp = NULL;\n                    }\n                }\n\n                SetFocus( GetDesktopWindow() );\n                KillTimer( hWnd, 0 );\n                g_TimerActive = FALSE;\n\n                DeleteObject( hTimerFont );\n                DeleteObject( hNegativeTimerFont );\n                DeleteDC( hdcScreen );\n                DeleteDC( hdcScreenCompat );\n                DeleteDC( hdcScreenSaveCompat );\n                DeleteDC( hdcScreenCursorCompat );\n                DeleteObject( hbmpCompat );\n                EnableDisableScreenSaver( TRUE );\n                EnableDisableOpacity( hWnd, FALSE );\n\n            } else {\n\n                SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 );\n                if( !g_Zoomed ) {\n\n                    g_Zoomed = TRUE;\n                    g_DrawingShape = FALSE;\n                    OutputDebug( L\"Zoom on\\n\");\n\n#ifdef __ZOOMIT_POWERTOYS__\n                    if( g_StartedByPowerToys )\n                    {\n                        Trace::ZoomItActivateZoom();\n                    }\n#endif // __ZOOMIT_POWERTOYS__\n\n                    // Hide the cursor before capturing if in live zoom\n                    if( g_hWndLiveZoom != nullptr )\n                    {\n                        OutputDebug(L\"Hide cursor\\n\");\n                        SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 );\n                        SendMessage( g_hWndLiveZoom, WM_TIMER, 0, 0 );\n                        SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, FALSE, 0 );\n                    }\n\n                    // Get screen DCs\n                    hdcScreen = CreateDC(L\"DISPLAY\", static_cast<PTCHAR>(NULL),\n                            static_cast<PTCHAR>(NULL), static_cast<CONST DEVMODE *>(NULL));\n                    hdcScreenCompat = CreateCompatibleDC(hdcScreen); \n                    hdcScreenSaveCompat = CreateCompatibleDC(hdcScreen); \n                    hdcScreenCursorCompat = CreateCompatibleDC(hdcScreen); \n\n                    // Determine what monitor we're on\n                    GetCursorPos(&cursorPos);\n                    UpdateMonitorInfo( cursorPos, &monInfo );\n                    width = monInfo.rcMonitor.right - monInfo.rcMonitor.left;\n                    height = monInfo.rcMonitor.bottom - monInfo.rcMonitor.top;\n                    OutputDebug( L\"ZOOM x: %d y: %d width: %d height: %d zoomLevel: %g\\n\",\n                            cursorPos.x, cursorPos.y, width, height, zoomLevel );\n\n                    // Create display bitmap\n                    bmp.bmBitsPixel = static_cast<BYTE>(GetDeviceCaps(hdcScreen, BITSPIXEL));\n                    bmp.bmPlanes = static_cast<BYTE>(GetDeviceCaps(hdcScreen, PLANES));\n                    bmp.bmWidth = width;\n                    bmp.bmHeight = height;\n                    bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8; \n                    hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight, \n                        bmp.bmPlanes, bmp.bmBitsPixel, static_cast<CONST VOID *>(NULL));\n                     SelectObject(hdcScreenCompat, hbmpCompat); \n\n                    // Create saved bitmap\n                    hbmpDrawingCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight, \n                        bmp.bmPlanes, bmp.bmBitsPixel, static_cast<CONST VOID *>(NULL));\n                    SelectObject(hdcScreenSaveCompat, hbmpDrawingCompat);\n\n                    // Create cursor save bitmap\n                    // (have to accomodate large fonts and LiveZoom pen scaling)\n                    hbmpCursorCompat = CreateBitmap( MAX_LIVE_PEN_WIDTH+CURSOR_ARM_LENGTH*2,\n                        MAX_LIVE_PEN_WIDTH+CURSOR_ARM_LENGTH*2, bmp.bmPlanes,\n                        bmp.bmBitsPixel, static_cast<CONST VOID *>(NULL));\n                    SelectObject(hdcScreenCursorCompat, hbmpCursorCompat);\n\n                    // Create typing font\n                    g_LogFont.lfHeight = height / 15;\n                    if (g_LogFont.lfHeight < 20)\n                        g_LogFont.lfQuality = NONANTIALIASED_QUALITY;\n                    else\n                        g_LogFont.lfQuality = ANTIALIASED_QUALITY;\n                    hTypingFont = CreateFontIndirect(&g_LogFont);\n                    SelectObject(hdcScreenCompat, hTypingFont);\n                    SetTextColor(hdcScreenCompat, g_PenColor & 0xFFFFFF);\n                    SetBkMode(hdcScreenCompat, TRANSPARENT);\n\n                    // Use the screen DC unless recording, because it contains the yellow border\n                    HDC hdcSource = hdcScreen;\n                    if( g_RecordToggle ) try {\n\n                        auto capture = CaptureScreenshot( winrt::DirectXPixelFormat::B8G8R8A8UIntNormalized );\n                        auto bytes = CopyBytesFromTexture( capture );\n\n                        D3D11_TEXTURE2D_DESC desc;\n                        capture->GetDesc( &desc );\n                        BITMAPINFO bitmapInfo = {};\n                        bitmapInfo.bmiHeader.biSize = sizeof bitmapInfo.bmiHeader;\n                        bitmapInfo.bmiHeader.biWidth = desc.Width;\n                        bitmapInfo.bmiHeader.biHeight = -static_cast<LONG>(desc.Height);\n                        bitmapInfo.bmiHeader.biPlanes = 1;\n                        bitmapInfo.bmiHeader.biBitCount = 32;\n                        bitmapInfo.bmiHeader.biCompression = BI_RGB;\n                        void *bits;\n                        auto dib = CreateDIBSection( NULL, &bitmapInfo, DIB_RGB_COLORS, &bits, nullptr, 0 );\n                        if( dib ) {\n\n                            CopyMemory( bits, bytes.data(), bytes.size() );\n                            auto hdcCapture = CreateCompatibleDC( hdcScreen );\n                            SelectObject( hdcCapture, dib );\n                            hdcSource = hdcCapture;\n                        }\n\n                    } catch( const winrt::hresult_error& ) {} // on any failure, fall back to the screen DC\n\n                    bool captured = hdcSource != hdcScreen;\n\n                    // paint the initial bitmap\n                    BitBlt( hdcScreenCompat, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcSource,\n                        captured ? 0 : monInfo.rcMonitor.left, captured ? 0 : monInfo.rcMonitor.top, SRCCOPY|CAPTUREBLT );\n                    BitBlt( hdcScreenSaveCompat, 0, 0, bmp.bmWidth, bmp.bmHeight, hdcSource,\n                        captured ? 0 : monInfo.rcMonitor.left, captured ? 0 : monInfo.rcMonitor.top, SRCCOPY|CAPTUREBLT );\n\n                    if( captured )\n                    {\n                        OutputDebug(L\"Captured screen\\n\");\n                        auto bitmap = GetCurrentObject( hdcSource, OBJ_BITMAP );\n                        DeleteObject( bitmap );\n                        DeleteDC( hdcSource );\n                    }\n\n                    // Create drawing pen\n                    hDrawingPen = CreatePen(PS_SOLID, g_PenWidth, g_PenColor & 0xFFFFFF);\n\n                    g_BlankedScreen = FALSE;\n                    g_HaveTyped = FALSE;\n                    g_Drawing = FALSE;\n                    g_TypeMode = TypeModeOff;\n                    g_HaveDrawn = FALSE;\n                    EnableDisableStickyKeys( TRUE );\n    \n                    // Go full screen\n                    g_ActiveWindow = GetForegroundWindow();\n                    OutputDebug( L\"active window: %x\\n\", PtrToLong(g_ActiveWindow) );\n\n                    if( lParam != LIVE_DRAW_ZOOM) {\n\n                        OutputDebug(L\"Calling ShowMainWindow\\n\");\n                        ShowMainWindow(hWnd, monInfo, width, height);\n                    }\n                \n                    // Start telescoping zoom. Lparam is non-zero if this\n                    // was a real hotkey and not the message we send ourself to enter\n                    // unzoomed drawing mode.\n\n                    //\n                    // Are we switching from live zoom to standard zoom?\n                    //\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n                    if( IsWindowVisible( g_hWndLiveZoom ) && !g_LiveZoomLevelOne ) {\n#else\n                    if( IsWindowVisible( g_hWndLiveZoom )) {\n#endif\n\n                        // Enter drawing mode\n                        OutputDebug(L\"Enter liveZoom draw\\n\");\n                        g_LiveZoomSourceRect = *reinterpret_cast<RECT *>(SendMessage( g_hWndLiveZoom, WM_USER_GET_SOURCE_RECT, 0, 0 ));\n                        g_LiveZoomLevel = *reinterpret_cast<float*>(SendMessage(g_hWndLiveZoom, WM_USER_GET_ZOOM_LEVEL, 0, 0));\n                        \n                        // Set live zoom level to 1 in preparation of us being full screen static\n                        zoomLevel = 1.0;\n                        zoomTelescopeTarget = 1.0;\n                        if (lParam != LIVE_DRAW_ZOOM) {\n\n                            g_ZoomOnLiveZoom = TRUE;\n                        }\n\n                        UpdateWindow( hWnd ); // overwrites where cursor erased\n                        if( lParam != SHALLOW_ZOOM )\n                        {\n                            // Put the drawing cursor where the magnified cursor was\n                            OutputDebug(L\"Setting cursor\\n\");\n\n                            if (lParam != LIVE_DRAW_ZOOM)\n                            {\n                                cursorPos = ScalePointInRects( cursorPos, g_LiveZoomSourceRect, monInfo.rcMonitor );\n                                SetCursorPos( cursorPos.x, cursorPos.y );\n                                UpdateWindow( hWnd ); // overwrites where cursor erased\n                                SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y ));\n                            }\n                        }\n                        else\n                        {\n                            InvalidateRect( hWnd, NULL, FALSE );\n                        }\n                        UpdateWindow( hWnd );\n                        if( g_RecordToggle )\n                        {\n                            g_SelectRectangle.UpdateOwner( hWnd );\n                        }\n                        if( lParam != LIVE_DRAW_ZOOM ) {\n\n                            OutputDebug(L\"Calling ShowMainWindow 2\\n\");\n\n                            ShowWindow( g_hWndLiveZoom, SW_HIDE );\n                        }\n\n                    } else if( lParam != 0 && lParam != LIVE_DRAW_ZOOM ) {\n\n                        zoomTelescopeStep = ZOOM_LEVEL_STEP_IN;\n                        zoomTelescopeTarget = g_ZoomLevels[g_SliderZoomLevel];\n                        if( g_AnimateZoom ) \n                            zoomLevel = static_cast<float>(1.0) * zoomTelescopeStep; \n                        else\n                            zoomLevel = zoomTelescopeTarget;\n                        SetTimer( hWnd, 1, ZOOM_LEVEL_STEP_TIME, NULL );\n                    }\n\n                } else {\n\n                    OutputDebug( L\"Zoom off: don't animate=%d\\n\", lParam );\n                    // turn off liveDraw\n                    SetLayeredWindowAttributes(hWnd, 0, 255, LWA_ALPHA);\n\n                    if( lParam != SHALLOW_DESTROY && !g_ZoomOnLiveZoom && g_AnimateZoom &&\n                        g_TelescopeZoomOut && zoomTelescopeTarget != 1 ) {\n\n                        // Start telescoping zoom. \n                        zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT;\n                        zoomTelescopeTarget = 1.0;\n                        SetTimer( hWnd, 2, ZOOM_LEVEL_STEP_TIME, NULL );\n\n                    } else {\n\n                        // Simulate timer expiration\n                        zoomTelescopeStep = 0;\n                        zoomTelescopeTarget = zoomLevel = 1.0;\n                        SendMessage( hWnd, WM_TIMER, 2, lParam );\n                    }\n                }\n            }\n            break;\n        }\n        return TRUE;\n\n    case WM_POINTERUPDATE: {\n        penInverted = IsPenInverted(wParam);\n        OutputDebug( L\"WM_POINTERUPDATE: contact: %d button down: %d X: %d Y: %d\\n\",\n            IS_POINTER_INCONTACT_WPARAM(wParam),\n            penInverted,\n            GET_X_LPARAM(lParam),\n            GET_Y_LPARAM(lParam));\n        if( penInverted != g_PenInverted) {\n\n            g_PenInverted = penInverted;\n            if (g_PenInverted) {\n                if (PopDrawUndo(hdcScreenCompat, &drawUndoList, width, height)) {\n\n                    SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, prevPt);\n                    InvalidateRect(hWnd, NULL, FALSE);\n                }\n            }\n        } else if( g_PenDown && !penInverted) {\n\n            SendPenMessage(hWnd, WM_MOUSEMOVE, lParam);\n        }\n        }\n        return TRUE;\n\n    case WM_POINTERUP:\n        OutputDebug(L\"WM_POINTERUP\\n\");\n        penInverted = IsPenInverted(wParam);\n        if (!penInverted) {\n\n            SendPenMessage(hWnd, WM_LBUTTONUP, lParam);\n            SendPenMessage(hWnd, WM_RBUTTONDOWN, lParam);\n            g_PenDown = FALSE;\n        }\n        break;\n\n    case WM_POINTERDOWN: \n        OutputDebug(L\"WM_POINTERDOWN\\n\");\n        penInverted = IsPenInverted(wParam);\n        if (!penInverted) {\n\n            g_PenDown = TRUE;\n\n            // Enter drawing mode\n            SendPenMessage(hWnd, WM_LBUTTONDOWN, lParam);\n            SendPenMessage(hWnd, WM_MOUSEMOVE, lParam);\n            SendPenMessage(hWnd, WM_LBUTTONUP, lParam);\n            SendPenMessage(hWnd, WM_MOUSEMOVE, lParam);\n            PopDrawUndo(hdcScreenCompat, &drawUndoList, width, height);\n\n            // Enter tracing mode\n            SendPenMessage(hWnd, WM_LBUTTONDOWN, lParam);\n        }\n        break;\n\n    case WM_KILLFOCUS:\n        if( ( g_RecordCropping == FALSE ) && g_Zoomed && !g_bSaveInProgress ) {\n\n            // Turn off zoom if not in liveDraw\n            DWORD layeringFlag;\n            GetLayeredWindowAttributes(hWnd, NULL, NULL, &layeringFlag);\n            if( !(layeringFlag & LWA_COLORKEY)) {\n\n                PostMessage(hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0);\n            }\n        }\n        break;\n\n    case WM_MOUSEWHEEL:\n\n        //\n        // Zoom or modify break timer\n        //\n        if( GET_WHEEL_DELTA_WPARAM(wParam) < 0 ) \n            wParam -= (WHEEL_DELTA-1) << 16;\n        else \n            wParam += (WHEEL_DELTA-1) << 16;\n        delta = GET_WHEEL_DELTA_WPARAM(wParam)/WHEEL_DELTA;\n        OutputDebug( L\"mousewheel: wParam: %d delta: %d\\n\", \n                GET_WHEEL_DELTA_WPARAM(wParam), delta );\n        if( g_Zoomed ) {\n            \n            if( g_TypeMode == TypeModeOff ) {\n\n                if( g_Drawing && (LOWORD( wParam ) & MK_CONTROL) ) {\n\n                    ResizePen( hWnd, hdcScreenCompat, hdcScreenCursorCompat, prevPt,\n                        g_Tracing, &g_Drawing, g_LiveZoomLevel, TRUE, g_PenWidth + delta );\n\n                // Perform static zoom unless in liveDraw\n                } else if( !( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) ) {\n\n                    if( delta > 0 ) zoomIn = TRUE;\n                    else {\n                        zoomIn = FALSE;\n                        delta = -delta;\n                    }\n                    while( delta-- ) {\n\n                        if( zoomIn ) {\n                            \n                            if( zoomTelescopeTarget < ZOOM_LEVEL_MAX ) {\n\n                                if( zoomTelescopeTarget < 2 ) {\n\n                                    zoomTelescopeTarget = 2;\n\n                                } else {\n                            \n                                    // Start telescoping zoom\n                                    zoomTelescopeTarget = zoomTelescopeTarget * 2; \n                                }\n                                zoomTelescopeStep = ZOOM_LEVEL_STEP_IN; \n                                if( g_AnimateZoom ) \n                                    zoomLevel *= zoomTelescopeStep; \n                                else\n                                    zoomLevel = zoomTelescopeTarget;\n\n                                if( zoomLevel > zoomTelescopeTarget ) \n                                    zoomLevel = zoomTelescopeTarget;\n                                else\n                                    SetTimer( hWnd, 1, ZOOM_LEVEL_STEP_TIME, NULL );\n                            }\n\n                        } else if( zoomTelescopeTarget > ZOOM_LEVEL_MIN ) {\n\n                            // Let them more gradually zoom out from 2x to 1x\n                            if( zoomTelescopeTarget <= 2 ) {\n\n                                zoomTelescopeTarget *= .75; \n                                if( zoomTelescopeTarget < ZOOM_LEVEL_MIN ) \n                                    zoomTelescopeTarget = ZOOM_LEVEL_MIN;\n\n                            } else {\n\n                                zoomTelescopeTarget = zoomTelescopeTarget/2; \n                            }\n                            zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT; \n                            if( g_AnimateZoom ) \n                                zoomLevel *= zoomTelescopeStep; \n                            else\n                                zoomLevel = zoomTelescopeTarget;\n\n                            if( zoomLevel < zoomTelescopeTarget )\n                            {\n                                zoomLevel = zoomTelescopeTarget;\n                                // Force update on final step out\n                                InvalidateRect( hWnd, NULL, FALSE );\n                            }\n                            else\n                            {\n                                SetTimer( hWnd, 1, ZOOM_LEVEL_STEP_TIME, NULL );\n                            }\n                        }\n                    }\n                    if( zoomLevel != zoomTelescopeTarget ) {\n\n                        if( g_Drawing ) {\n\n                            if( !g_Tracing ) {\n\n                                RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n                            }\n                            //SetCursorPos( monInfo.rcMonitor.left + cursorPos.x, \n                            //\t\tmonInfo.rcMonitor.top + cursorPos.y );\n                        }\n                        InvalidateRect( hWnd, NULL, FALSE );\n                    }\t\t\t\t\n                }\n            } else {\n\n                // Resize the text font\n                if( (delta > 0 && g_FontScale > -20) || (delta < 0 && g_FontScale < 50 )) {\n\n                    ClearTypingCursor(hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen);\n\n                    g_FontScale -= delta;\n                    if( g_FontScale == 0 ) g_FontScale = 1;\n                    // Set lParam to 0 as part of message to keyup hander\n                    DeleteObject(hTypingFont);\n                    g_LogFont.lfHeight = max((int)(height / zoomLevel) / g_FontScale, 12);\n                    if (g_LogFont.lfHeight < 20)\t\n                        g_LogFont.lfQuality = NONANTIALIASED_QUALITY;\n                    else\n                        g_LogFont.lfQuality = ANTIALIASED_QUALITY;\n                    hTypingFont = CreateFontIndirect(&g_LogFont);\n                    SelectObject(hdcScreenCompat, hTypingFont);\n\n                    DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc );\n                }\n            }\n        } else if( g_TimerActive && (breakTimeout > 0 || delta )) {\n\n            if( delta ) {\n\n                if( breakTimeout < 0 ) breakTimeout = 0;\n                if( breakTimeout % 60 ) {\n                    breakTimeout += (60 - breakTimeout % 60);\n                    delta--;\n                }\n                breakTimeout += delta * 60;\n\n            } else {\n\n                if( breakTimeout % 60 ) {\n                    breakTimeout -= breakTimeout % 60;\n                    delta--;\n                }\n                breakTimeout -= delta * 60;\n            }\n            if( breakTimeout < 0 ) breakTimeout = 0;\n            KillTimer( hWnd, 0 );\n            SetTimer( hWnd, 0, 1000, NULL );\n            InvalidateRect( hWnd, NULL, TRUE );\n        }\n\n        if( zoomLevel != 1 && g_Drawing ) {\n\n            // Constrain the mouse to the visible region\n            boundRc = BoundMouse( zoomTelescopeTarget, &monInfo, width, height, &cursorPos );\n\n        } else {\n\n            ClipCursor( NULL );\n        }\n        return TRUE;\n\n    case WM_IME_CHAR:\n    case WM_CHAR:\n\n        if( (g_TypeMode != TypeModeOff) && iswprint(static_cast<TCHAR>(wParam)) || (static_cast<TCHAR>(wParam) == L'&')) {\n            g_HaveTyped = TRUE;\n\n            TCHAR\t vKey = static_cast<TCHAR>(wParam);\n\n            g_HaveDrawn = TRUE;\n\n            // Clear typing cursor\n            rc.left = textPt.x;\n            rc.top = textPt.y;\n            ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen );\n            if (g_TypeMode == TypeModeRightJustify) {\n\n                if( !g_TextBuffer.empty() || !g_TextBufferPreviousLines.empty() ) {\n\n                    PopDrawUndo(hdcScreenCompat, &drawUndoList, width, height); //***\n                }\n                PushDrawUndo(hdcScreenCompat, &drawUndoList, width, height);\n\n                // Restore previous lines.\n                wParam = 'X';\n                DrawText(hdcScreenCompat, reinterpret_cast<PTCHAR>(&wParam), 1, &rc, DT_CALCRECT);\n                const auto lineHeight = rc.bottom - rc.top;\n\n                rc.top -= static_cast< LONG >( g_TextBufferPreviousLines.size() ) * lineHeight;\n\n                // Draw the current character on the current line.\n                g_TextBuffer += vKey;\n                drawAllRightJustifiedLines( lineHeight );\n            }\n            else {\n                DrawText( hdcScreenCompat, &vKey, 1, &rc, DT_CALCRECT|DT_NOPREFIX);\n                DrawText( hdcScreenCompat, &vKey, 1, &rc, DT_LEFT|DT_NOPREFIX);\n                textPt.x += rc.right - rc.left;\n            }\n            InvalidateRect( hWnd, NULL, TRUE );\n\n            // Save the key for undo\n            P_TYPED_KEY newKey = static_cast<P_TYPED_KEY>(malloc( sizeof(TYPED_KEY) ));\n            newKey->rc = rc;\n            newKey->Next = typedKeyList;\n            typedKeyList = newKey;\n\n            // Draw the typing cursor\n            DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc );\n            return FALSE;\n        }\n        break;\n\n    case WM_KEYUP:\n        if( wParam == 'T' && (g_TypeMode == TypeModeOff)) {\n\n            // lParam is 0 when we're resizing the font and so don't have a cursor that\n            // we need to restore\n            if( !g_Drawing && lParam == 0 ) {\n\n                OutputDebug(L\"Entering typing mode and resetting cursor position\\n\");\n                SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y));\n            } \n\n            // Do they want to right-justify text?\n            OutputDebug(L\"Keyup Shift: %x\\n\", GetAsyncKeyState(VK_SHIFT));\n            if(GetAsyncKeyState(VK_SHIFT) != 0 ) {\n\n                g_TypeMode = TypeModeRightJustify;\n                g_TextBuffer.clear();\n\n                // Also empty all previous lines\n                g_TextBufferPreviousLines = {};\n            }\n            else {\n\n                g_TypeMode = TypeModeLeftJustify;\n            }\n            textStartPt = cursorPos;\n            textPt = prevPt;\n\n            g_HaveTyped = FALSE;\n\n            // Get a font of a decent size\n            DeleteObject( hTypingFont );\n            g_LogFont.lfHeight = max( (int) (height / zoomLevel)/g_FontScale, 12 );\n            if (g_LogFont.lfHeight < 20)\n                g_LogFont.lfQuality = NONANTIALIASED_QUALITY;\n            else\n                g_LogFont.lfQuality = ANTIALIASED_QUALITY;\n            hTypingFont = CreateFontIndirect( &g_LogFont );\n            SelectObject( hdcScreenCompat, hTypingFont );\n            \n            // If lparam == 0 that means that we sent the message as part of a font resize\n            if( g_Drawing && lParam != 0) {\n\n                RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n                PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height );\n            \n            } else if( !g_Drawing ) {\n\n                textPt = cursorPos;\n            }\n\n            // Draw the typing cursor\n            DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc, true );\n            prevPt = textPt;\n        }\n        break;\n\n    case WM_KEYDOWN:\n\n        if( (g_TypeMode != TypeModeOff) && g_HaveTyped && static_cast<char>(wParam) != VK_UP && static_cast<char>(wParam) != VK_DOWN &&\n            (isprint( static_cast<char>(wParam)) || \n            wParam == VK_RETURN || wParam == VK_DELETE || wParam == VK_BACK )) {\n\n            if( wParam == VK_RETURN ) {\n\n                // Clear the typing cursor\n                ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen );\n\n                if( g_TypeMode == TypeModeRightJustify )\n                {\n                    g_TextBufferPreviousLines.push_back( g_TextBuffer );\n                    g_TextBuffer.clear();\n                }\n                else\n                {\n                    // Insert a fake return key in the list to undo.\n                    P_TYPED_KEY newKey = static_cast<P_TYPED_KEY>(malloc(sizeof(TYPED_KEY)));\n                    newKey->rc.left = textPt.x;\n                    newKey->rc.top = textPt.y;\n                    newKey->rc.right = newKey->rc.left;\n                    newKey->rc.bottom = newKey->rc.top;\n                    newKey->Next = typedKeyList;\n                    typedKeyList = newKey;\n                }\n\n                wParam = 'X';\n                DrawText( hdcScreenCompat, reinterpret_cast<PTCHAR>(&wParam), 1, &rc, DT_CALCRECT );\n                textPt.x = prevPt.x; // + g_PenWidth;\n                textPt.y += rc.bottom - rc.top;\n\n                // Draw the typing cursor\n                DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc );\n            } else if( wParam == VK_DELETE || wParam == VK_BACK ) {\n\n                P_TYPED_KEY\tdeletedKey = typedKeyList;\n                if( deletedKey ) {\n\n                    // Clear the typing cursor\n                    ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen );\n\n                    if( g_TypeMode == TypeModeRightJustify ) {\n\n                        if( !g_TextBuffer.empty() || !g_TextBufferPreviousLines.empty() ) {\n\n                            PopDrawUndo( hdcScreenCompat, &drawUndoList, width, height );\n                        }\n                        PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height );\n\n                        rc.left = textPt.x;\n                        rc.top = textPt.y;\n\n                        // Restore the previous lines.\n                        wParam = 'X';\n                        DrawText( hdcScreenCompat, reinterpret_cast<PTCHAR>(&wParam), 1, &rc, DT_CALCRECT );\n                        const auto lineHeight = rc.bottom - rc.top;\n\n                        const bool lineWasEmpty = g_TextBuffer.empty();\n                        drawAllRightJustifiedLines( lineHeight, true );\n                        if( lineWasEmpty && !g_TextBufferPreviousLines.empty() )\n                        {\n                            g_TextBuffer = g_TextBufferPreviousLines.back();\n                            g_TextBufferPreviousLines.pop_back();\n                            textPt.y -= lineHeight;\n                        }\n                    }\n                    else {\n                        RECT rect = deletedKey->rc;\n                        if (g_BlankedScreen) {\n\n                            BlankScreenArea(hdcScreenCompat, &rect, g_BlankedScreen);\n                        }\n                        else {\n\n                            BitBlt(hdcScreenCompat, rect.left, rect.top, rect.right - rect.left,\n                                rect.bottom - rect.top, hdcScreenSaveCompat, rect.left, rect.top, SRCCOPY | CAPTUREBLT );\n                        }\n                        InvalidateRect( hWnd, NULL, FALSE );\n\n                        textPt.x = rect.left;\n                        textPt.y = rect.top;\n\n                        typedKeyList = deletedKey->Next;\n                        free(deletedKey);\n\n                        // Refresh cursor if we deleted the last key\n                        if( typedKeyList == NULL ) {\n\n                            SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y ) );\n                        }\n                    }\n                    DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc );\n                }\n            } \n            break;\n        }\n        switch (wParam) { \n        case 'R':\n        case 'B':\n        case 'Y':\n        case 'O':\n        case 'G':\n        case 'X':\n        case 'P':\n            if( (g_Zoomed || g_TimerActive) && (g_TypeMode == TypeModeOff)) {\n            \n                PDWORD\tpenColor;\n                if( g_TimerActive )\n                    penColor = &g_BreakPenColor;\n                else\n                    penColor = &g_PenColor;\n\n                if( wParam == 'R' )\t\t *penColor = COLOR_RED;\n                else if( wParam == 'G' ) *penColor = COLOR_GREEN;\n                else if( wParam == 'B' ) *penColor = COLOR_BLUE;\n                else if( wParam == 'Y' ) *penColor = COLOR_YELLOW;\n                else if( wParam == 'O' ) *penColor = COLOR_ORANGE;\n                else if( wParam == 'P' ) *penColor = COLOR_PINK;\n                else if( wParam == 'X' )\n                {\n                    if( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED )\n                    {\n                        // Blur is not supported in LiveDraw\n                        break;\n                    }\n                    *penColor = COLOR_BLUR;\n                }\n\n                bool shift = GetKeyState( VK_SHIFT ) & 0x8000;\n                if( shift && ( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) )\n                {\n                    // Highlight is not supported in LiveDraw\n                    break;\n                }\n\n                reg.WriteRegSettings( RegSettings );\n                DeleteObject( hDrawingPen );\n                SetTextColor( hdcScreenCompat, *penColor );\n\n                // Highlight and blur level\n                if( shift && *penColor != COLOR_BLUR )\n                {\n                    *penColor |= (g_AlphaBlend << 24);\n                }\n                else\n                {\n                    if( *penColor == COLOR_BLUR )\n                    {\n                        g_BlurRadius = shift ? STRONG_BLUR_RADIUS : NORMAL_BLUR_RADIUS;\n                    }\n                    *penColor |= (0xFF << 24);\n                }\n                hDrawingPen = CreatePen(PS_SOLID, g_PenWidth, *penColor & 0xFFFFFF);\n\n                SelectObject( hdcScreenCompat, hDrawingPen );\n                if( g_Drawing ) {\n\n                    SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y ));\t\t\t\t\n                \n                } else if( g_TimerActive ) {\n    \n                    InvalidateRect( hWnd, NULL, FALSE );\t\t\t\t\n                \n                } else if( g_TypeMode != TypeModeOff ) {\n\n                    ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen );\n                    DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc );\n                    InvalidateRect( hWnd, NULL, FALSE );\n                }\n            }\n            break;\n\n        case 'Z':\n            if( (GetKeyState( VK_CONTROL ) & 0x8000 ) && g_HaveDrawn && !g_Tracing ) {\n\n                if( PopDrawUndo( hdcScreenCompat, &drawUndoList, width, height )) {\n                \n                    if( g_Drawing ) {\n\n                        SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n                        SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y ));\t\t\t\n                    }\n                    else {\n\n                        SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, prevPt);\n                    }\n                    InvalidateRect( hWnd, NULL, FALSE );\n                }\n            }\n            break;\n\n        case VK_SPACE:\n            if( g_Drawing && !g_Tracing ) {\n\n                SetCursorPos(  boundRc.left + (boundRc.right - boundRc.left)/2,\n                         boundRc.top + (boundRc.bottom - boundRc.top)/2 );\n                SendMessage( hWnd, WM_MOUSEMOVE, 0, \n                    MAKELPARAM( (boundRc.right - boundRc.left)/2,\n                                (boundRc.bottom - boundRc.top)/2 ));\n            }\n            break;\n\n        case 'W':\n        case 'K':\n            // Block user-driven sketch pad in liveDraw\n            if( lParam != LIVE_DRAW_ZOOM\n                && ( GetWindowLongPtr( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED ) )\n            {\n                break;\n            }\n\n            // Don't allow screen blanking while we've got the typing cursor active\n            // because we don't really handle going from white to black.\n            if( g_Zoomed && (g_TypeMode == TypeModeOff)) {\n\n                if( !g_Drawing ) {\n\n                    SendMessage( hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM( cursorPos.x, cursorPos.y));\n                }\n                // Restore area where cursor was previously\n                RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n                PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height );\n                g_BlankedScreen = static_cast<int>(wParam);\n                rc.top = rc.left = 0;\n                rc.bottom = height;\n                rc.right = width;\n                BlankScreenArea( hdcScreenCompat, &rc, g_BlankedScreen );\n                InvalidateRect( hWnd, NULL, FALSE );\n\n                // Save area that's going to be occupied by new cursor position\n                SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n                SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y ));\t\t\t\t\n            }\n            break;\n\n        case 'E':\n            // Don't allow erase while we have the typing cursor active\n            if( g_HaveDrawn && (g_TypeMode == TypeModeOff)) {\n\n                DeleteDrawUndoList( &drawUndoList );\n                g_HaveDrawn = FALSE;\n                OutputDebug(L\"Erase\\n\");\n                if(GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED) {\n                    SendMessage(hWnd, WM_KEYDOWN, 'K', 0);\n                }\n                else {\n                    BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth,\n                        bmp.bmHeight, hdcScreenSaveCompat, 0, 0, SRCCOPY | CAPTUREBLT);\n\n                    if (g_Drawing) {\n\n                        OutputDebug(L\"Erase: draw cursor\\n\");\n                        SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, prevPt);\n                        DrawCursor(hdcScreenCompat, prevPt, zoomLevel, width, height);\n                        g_HaveDrawn = TRUE;\n                    }\n                }\n                InvalidateRect( hWnd, NULL, FALSE );\n                g_BlankedScreen = FALSE;\n            } \n            break;\n\n        case VK_UP:\n            SendMessage( hWnd, WM_MOUSEWHEEL, \n                MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 || GetAsyncKeyState( VK_RCONTROL ) != 0 ? \n                        MK_CONTROL: 0, WHEEL_DELTA), 0 );\n            return TRUE;\n\n        case VK_DOWN:\n            SendMessage( hWnd, WM_MOUSEWHEEL, \n                MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 || GetAsyncKeyState( VK_RCONTROL ) != 0 ? \n                        MK_CONTROL: 0, -WHEEL_DELTA), 0 );\n            return TRUE;\n\n        case VK_LEFT:\n        case VK_RIGHT:\n            if( wParam == VK_RIGHT ) delta = 10;\n            else\t\t\t\t\t  delta = -10;\n            if( g_TimerActive && (breakTimeout > 0 || delta )) {\n\n                if( breakTimeout < 0 ) breakTimeout = 0;\n                breakTimeout += delta;\n                breakTimeout -= (breakTimeout % 10);\n                if( breakTimeout < 0 ) breakTimeout = 0;\n                KillTimer( hWnd, 0 );\n                SetTimer( hWnd, 0, 1000, NULL );\n                InvalidateRect( hWnd, NULL, TRUE );\n            }\n            break;\n            \n        case VK_ESCAPE: \n            if( g_TypeMode != TypeModeOff) {\n\n                // Turn off\n                SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 );\n    \n            } else {\n\n                forcePenResize = TRUE;\n                PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 );\n\n                // In case we were in liveDraw\n                if( GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED) {\n\n                    KillTimer(hWnd, 3);\n                    LONG_PTR exStyle = GetWindowLongPtr(hWnd, GWL_EXSTYLE);\n                    SetWindowLongPtr(hWnd, GWL_EXSTYLE, exStyle & ~WS_EX_LAYERED);\n                    pMagSetWindowFilterList( g_hWndLiveZoomMag, MW_FILTERMODE_EXCLUDE, 1, &hWnd );\n                    SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, TRUE, 0 );\n                }\n            }\n            break;\n        }\n        return TRUE;\n\n    case WM_RBUTTONDOWN:\n        SendMessage( hWnd, WM_USER_EXIT_MODE, 0, 0 );\n        break;\n\n    case WM_MOUSEMOVE:\n        OutputDebug(L\"MOUSEMOVE: zoomed: %d drawing: %d tracing: %d\\n\",\n            g_Zoomed, g_Drawing, g_Tracing);\n\n        OutputDebug(L\"Window visible: %d Topmost: %d\\n\", IsWindowVisible(hWnd), GetWindowLong(hWnd, GWL_EXSTYLE)& WS_EX_TOPMOST);\n\n        if( g_Zoomed && (g_TypeMode == TypeModeOff) && !g_bSaveInProgress ) {\n\n            if( g_Drawing ) {\n\n                POINT currentPt;\n\n                // Are we in pen mode on a tablet?\n                lParam = ScalePenPosition( zoomLevel, &monInfo, boundRc, message, lParam);\t\n                currentPt.x = LOWORD(lParam);\n                currentPt.y = HIWORD(lParam);\n\n                if(lParam == 0) {\n\n                    // Drop it\n                    OutputDebug(L\"Mousemove: Dropping\\n\");\n                    break;\n\n                } else if(g_DrawingShape) {\n\n                    SetROP2(hdcScreenCompat, R2_NOTXORPEN); \n     \n                    // If a previous target rectangle exists, erase \n                    // it by drawing another rectangle on top. \n                    if( g_rcRectangle.top != g_rcRectangle.bottom ||\n                        g_rcRectangle.left != g_rcRectangle.right )\n                    {\n                        if( prevPenWidth != g_PenWidth )\n                        {\n                            auto penWidth = g_PenWidth;\n                            g_PenWidth = prevPenWidth;\n\n                            auto prevPen = CreatePen( PS_SOLID, g_PenWidth, g_PenColor & 0xFFFFFF );\n                            SelectObject( hdcScreenCompat, prevPen );\n\n                            DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle );\n\n                            g_PenWidth = penWidth;\n                            SelectObject( hdcScreenCompat, hDrawingPen );\n                            DeleteObject( prevPen );\n                        }\n                        else\n                        {\n                            DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle );\n                        }\n                    }\n\n                    // Save the coordinates of the target rectangle. \n                    // Avoid invalid rectangles by ensuring that the\n                    // value of the left coordinate is greater than \n                    // that of the right, and that the value of the \n                    // bottom coordinate is greater than that of \n                    // the top. \t \n                    if( g_DrawingShape == DRAW_LINE ||\n                        g_DrawingShape == DRAW_ARROW ) {\n\n                        g_rcRectangle.right = static_cast<LONG>(LOWORD(lParam));\n                        g_rcRectangle.bottom = static_cast<LONG>(HIWORD(lParam));\n\n                    } else {\n\n                        if ((g_RectangleAnchor.x < currentPt.x) && \n                                (g_RectangleAnchor.y > currentPt.y)) {\n\n                            SetRect(&g_rcRectangle, g_RectangleAnchor.x, currentPt.y, \n                                currentPt.x, g_RectangleAnchor.y); \n\n                        } else if ((g_RectangleAnchor.x > currentPt.x) && \n                                (g_RectangleAnchor.y > currentPt.y )) {\n\n                            SetRect(&g_rcRectangle, currentPt.x, \n                                currentPt.y, g_RectangleAnchor.x,g_RectangleAnchor.y); \n\n                        } else if ((g_RectangleAnchor.x > currentPt.x) && \n                                (g_RectangleAnchor.y < currentPt.y )) {\n\n                            SetRect(&g_rcRectangle, currentPt.x, g_RectangleAnchor.y, \n                                g_RectangleAnchor.x, currentPt.y ); \n                        } else {\n\n                            SetRect(&g_rcRectangle, g_RectangleAnchor.x, g_RectangleAnchor.y, \n                                currentPt.x, currentPt.y ); \n                        }\n                    }\n\n                    if (g_rcRectangle.left != g_rcRectangle.right ||\n                        g_rcRectangle.top != g_rcRectangle.bottom) {\n\n                        // Draw the new target rectangle. \n                        DrawShape(g_DrawingShape, hdcScreenCompat, &g_rcRectangle);\n                        OutputDebug(L\"SHAPE: (%d, %d) - (%d, %d)\\n\", g_rcRectangle.left, g_rcRectangle.top, \n                            g_rcRectangle.right, g_rcRectangle.bottom);\n                    }\n\n                    prevPenWidth = g_PenWidth;\n                    SetROP2( hdcScreenCompat, R2_NOP );\n                }\n                else if (g_Tracing) {\n\n                    OutputDebug(L\"Mousemove: Tracing\\n\");\n\n                    g_HaveDrawn = TRUE;\n                    Gdiplus::Graphics\tdstGraphics(hdcScreenCompat);\n                    if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n                    {\n                        dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n                    }\n                    Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n                    Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n                    pen.SetLineCap(Gdiplus::LineCapRound, Gdiplus::LineCapRound, Gdiplus::DashCapRound);\n\n                    // If highlighting, use a double layer approach\n                    OutputDebug(L\"PenColor: %x\\n\", g_PenColor);\n                    OutputDebug(L\"Blur color: %x\\n\", COLOR_BLUR);\n                    if( (g_PenColor & 0xFFFFFF) == COLOR_BLUR) {\n\n                        OutputDebug(L\"BLUR\\n\");\n\n                        // Restore area where cursor was previously\n                        RestoreCursorArea(hdcScreenCompat, hdcScreenCursorCompat, prevPt);\n\n                        // Create a new bitmap that's the size of the area covered by the line + 2 * g_PenWidth\n                        Gdiplus::Rect lineBounds = GetLineBounds( prevPt, currentPt, g_PenWidth );\n                        Gdiplus::Bitmap* lineBitmap = DrawBitmapLine(lineBounds, prevPt, currentPt, &pen);\n                        Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap);\n                        BYTE* pPixels = static_cast<BYTE*>(lineData->Scan0);\n\n                        // Copy the contents of the screen bitmap to the temporary bitmap\n                        GetOldestUndo(drawUndoList);\n\n                        // Create a GDI bitmap that's the size of the lineBounds rectangle\n                        Gdiplus::Bitmap *blurBitmap = CreateGdiplusBitmap( hdcScreenCompat, // oldestUndo->hDc, \n                                            lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height);\n\n                        // Blur it\n                        BitmapBlur(blurBitmap);\n                        BlurScreen(hdcScreenCompat, &lineBounds, blurBitmap, pPixels);\n\n                        // Unlock the bits\n                        lineBitmap->UnlockBits(lineData);\n                        delete lineBitmap;\n                        delete blurBitmap;\n\n                        // Invalidate the updated rectangle\n                        InvalidateGdiplusRect( hWnd, lineBounds );\n\n                        // Save area that's going to be occupied by new cursor position\n                        SaveCursorArea(hdcScreenCursorCompat, hdcScreenCompat, currentPt);\n\n                        // Draw new cursor\n                        DrawCursor(hdcScreenCompat, currentPt, zoomLevel, width, height);\n                    } \n                    else if(PEN_COLOR_HIGHLIGHT(g_PenColor)) { \n\n                        // This is a highlighting pen color\n                        Gdiplus::Rect lineBounds = GetLineBounds(prevPt, currentPt, g_PenWidth);\n                        Gdiplus::Bitmap* lineBitmap = DrawBitmapLine(lineBounds, prevPt, currentPt, &pen);\n                        Gdiplus::BitmapData* lineData = LockGdiPlusBitmap(lineBitmap);\n                        BYTE* pPixels = static_cast<BYTE*>(lineData->Scan0);\n\n                        // Create a DIB section for efficient pixel manipulation\n                        BITMAPINFO bmi = { 0 };\n                        bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);\n                        bmi.bmiHeader.biWidth = lineBounds.Width;\n                        bmi.bmiHeader.biHeight = -lineBounds.Height;  // Top-down DIB\n                        bmi.bmiHeader.biPlanes = 1;\n                        bmi.bmiHeader.biBitCount = 32;  // 32 bits per pixel\n                        bmi.bmiHeader.biCompression = BI_RGB;\n\n                        VOID* pDIBBits;\n                        HBITMAP hDIB = CreateDIBSection(hdcScreenCompat, &bmi, DIB_RGB_COLORS, &pDIBBits, NULL, 0);\n\n                        HDC hdcDIB = CreateCompatibleDC(hdcScreenCompat);\n                        SelectObject(hdcDIB, hDIB);\n\n                        // Copy the relevant part of hdcScreenCompat to the DIB\n                        BitBlt(hdcDIB, 0, 0, lineBounds.Width, lineBounds.Height, hdcScreenCompat, lineBounds.X, lineBounds.Y, SRCCOPY);\n\n                        // Pointer to the DIB bits\n                        BYTE* pDestPixels = static_cast<BYTE*>(pDIBBits);\n\n                        // Pointer to screen bits\n                        HDC hdcDIBOrig;\n                        HBITMAP hDibOrigBitmap, hDibBitmap;\n                        P_DRAW_UNDO oldestUndo = GetOldestUndo(drawUndoList);\n                        BYTE* pDestPixels2 = CreateBitmapMemoryDIB(hdcScreenCompat, oldestUndo->hDc, &lineBounds, \n                                                &hdcDIBOrig, &hDibBitmap, &hDibOrigBitmap);\n\n                        for (int local_y = 0; local_y < lineBounds.Height; ++local_y) {\n                            for (int local_x = 0; local_x < lineBounds.Width; ++local_x) {\n                                int index = (local_y * lineBounds.Width * 4) + (local_x * 4); // Assuming 4 bytes per pixel\n                                // BYTE b = pPixels[index + 0];  // Blue channel\n                                // BYTE g = pPixels[index + 1];  // Green channel\n                                // BYTE r = pPixels[index + 2];  // Red channel\n                                BYTE a = pPixels[index + 3];  // Alpha channel\n\n                                // Check if this is a drawn pixel\n                                if (a != 0) {\n                                    // Assuming pDestPixels is a valid pointer to the destination bitmap's pixel data\n                                    BYTE destB = pDestPixels2[index + 0];  // Blue channel\n                                    BYTE destG = pDestPixels2[index + 1];  // Green channel\n                                    BYTE destR = pDestPixels2[index + 2];  // Red channel\n\n                                    // Create a COLORREF value from the destination pixel data\n                                    COLORREF currentPixel = RGB(destR, destG, destB);\n                                    // Blend the colors\n                                    COLORREF newPixel = BlendColors(currentPixel, g_PenColor);\n                                    // Update the destination pixel data with the new color\n                                    pDestPixels[index + 0] = GetBValue(newPixel);\n                                    pDestPixels[index + 1] = GetGValue(newPixel);\n                                    pDestPixels[index + 2] = GetRValue(newPixel);\n                                }\n                            }\n                        }\n\n                        // Copy the updated DIB back to hdcScreenCompat\n                        BitBlt(hdcScreenCompat, lineBounds.X, lineBounds.Y, lineBounds.Width, lineBounds.Height, hdcDIB, 0, 0, SRCCOPY);\n\n                        // Clean up\n                        DeleteObject(hDIB);\n                        DeleteDC(hdcDIB);\n\n                        SelectObject(hdcDIBOrig, hDibOrigBitmap);\n                        DeleteObject(hDibBitmap);\n                        DeleteDC(hdcDIBOrig);\n\n                        // Invalidate the updated rectangle\n                        InvalidateGdiplusRect(hWnd, lineBounds);\n                    }\n                    else {\n\n                        // Normal tracing\n                        dstGraphics.DrawLine(&pen, static_cast<INT>(prevPt.x), static_cast<INT>(prevPt.y),\n                                static_cast<INT>(currentPt.x), static_cast<INT>(currentPt.y));\n                    }\n\n                } else {\n\n                    OutputDebug(L\"Mousemove: Moving cursor\\n\");\n\n                    // Restore area where cursor was previously\n                    RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n                    \n                    // Save area that's going to be occupied by new cursor position\n                    SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, currentPt );\n\n                    // Draw new cursor\n                    DrawCursor( hdcScreenCompat, currentPt, zoomLevel, width, height );\n                }\n\n                if( g_DrawingShape ) {\n\n                    InvalidateRect( hWnd, NULL, FALSE );\n\n                } else {\n\n                    // Invalidate area just modified\n                    InvalidateCursorMoveArea( hWnd, zoomLevel, width, height, currentPt, prevPt, cursorPos );\n                }\n                prevPt = currentPt;\n\n                // In liveDraw we an miss the mouse up\n                if( GetWindowLong(hWnd, GWL_EXSTYLE) & WS_EX_LAYERED) {\n\n                    if((GetAsyncKeyState(VK_LBUTTON) & 0x8000) == 0) {\n\n                        OutputDebug(L\"LIVE_DRAW missed mouse up. Sending synthetic.\\n\");\n                        SendMessage(hWnd, WM_LBUTTONUP, wParam, lParam);\n                    }\n                }\n\n            } else {\n\n                cursorPos.x = LOWORD( lParam );\n                cursorPos.y = HIWORD( lParam );\n                InvalidateRect( hWnd, NULL, FALSE );\n            }\n        } else if( g_Zoomed && (g_TypeMode != TypeModeOff) && !g_HaveTyped ) {\n\n            ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen );\n            textPt.x = prevPt.x = LOWORD( lParam );\n            textPt.y = prevPt.y = HIWORD( lParam );\n\n            // Draw the typing cursor\n            DrawTypingCursor( hWnd, &textPt, hdcScreenCompat, hdcScreenCursorCompat, &cursorRc, true );\n            prevPt = textPt;\n            InvalidateRect( hWnd, NULL, FALSE );\n        }\n#if 0\n        {\n            static int index = 0;\n            OutputDebug( L\"%d: foreground: %x focus: %x (hwnd: %x)\\n\", \n                index++, (DWORD) PtrToUlong(GetForegroundWindow()),  PtrToUlong(GetFocus()), PtrToUlong(hWnd));\n        }\n#endif\n        return TRUE;\n    \n    case WM_LBUTTONDOWN:\n        g_StraightDirection = 0;\n\n        if( g_Zoomed && (g_TypeMode == TypeModeOff) && zoomTelescopeTarget == zoomLevel ) {\n\n            OutputDebug(L\"LBUTTONDOWN: drawing\\n\");\n\n            // Save current bitmap to undo history\n            if( g_HaveDrawn ) {\n\n                RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n            }\n            \n            // don't push undo if we sent this to ourselves for a pen resize\n            if( wParam != -1 ) {\n                \n                PushDrawUndo( hdcScreenCompat, &drawUndoList, width, height );\n\n            } else {\n\n                wParam = 0;\n            }\n\n            // Are we in pen mode on a tablet?\n            lParam = ScalePenPosition( zoomLevel, &monInfo, boundRc,\n                        message, lParam);\n\n            if (lParam == 0) {\n\n                // Drop it\n                break;\n\n            } else if( g_Drawing ) {\n\n                // is the user drawing a rectangle?\n                if( wParam & MK_CONTROL ||\n                    wParam & MK_SHIFT ||\n                    GetKeyState( VK_TAB ) < 0 ) {\n\n                    // Restore area where cursor was previously\n                    RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n\n                    if( wParam & MK_SHIFT && wParam & MK_CONTROL )\n                        g_DrawingShape = DRAW_ARROW;\n                    else if( wParam & MK_CONTROL ) \n                        g_DrawingShape = DRAW_RECTANGLE;\n                    else if( wParam & MK_SHIFT )\n                        g_DrawingShape = DRAW_LINE;\n                    else\n                        g_DrawingShape = DRAW_ELLIPSE;\n                    g_RectangleAnchor.x = LOWORD(lParam);\n                    g_RectangleAnchor.y = HIWORD(lParam);\n                    SetRect(&g_rcRectangle, g_RectangleAnchor.x, g_RectangleAnchor.y, \n                            g_RectangleAnchor.x, g_RectangleAnchor.y); \n\n                } else {\n\n                    Gdiplus::Graphics\tdstGraphics(hdcScreenCompat);\n                    if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n                    {\n                        dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n                    }\n                    Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n                    Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n                    Gdiplus::GraphicsPath path;\n                    pen.SetLineJoin(Gdiplus::LineJoinRound);\n                    path.AddLine(static_cast<INT>(prevPt.x), prevPt.y, prevPt.x, prevPt.y);\n                    dstGraphics.DrawPath(&pen, &path);\n                }\n                g_Tracing = TRUE;\n                SetROP2( hdcScreenCompat, R2_COPYPEN );\n                prevPt.x = LOWORD(lParam); \n                prevPt.y = HIWORD(lParam); \n                g_HaveDrawn = TRUE;\n        \n            } else {\n\n                OutputDebug(L\"Tracing on\\n\");\n\n                // Turn on drawing\n                if( !g_HaveDrawn ) {\n\n                    // refresh drawing bitmap with original screen image\n                    BitBlt(hdcScreenCompat, 0, 0, bmp.bmWidth,\n                        bmp.bmHeight, hdcScreenSaveCompat, 0, 0, SRCCOPY|CAPTUREBLT );\n                    g_HaveDrawn = TRUE;\n                }\n                DeleteObject( hDrawingPen );\n                hDrawingPen = CreatePen(PS_SOLID, g_PenWidth, g_PenColor & 0xFFFFFF);\n                SelectObject( hdcScreenCompat, hDrawingPen );\n\n                // is the user drawing a rectangle?\n                if( wParam & MK_CONTROL && g_Drawing ) {\n\n                    // Restore area where cursor was previously\n                    RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n\n                    // Configure rectangle drawing\n                    g_DrawingShape = TRUE;\n                    g_RectangleAnchor.x = LOWORD(lParam);\n                    g_RectangleAnchor.y = HIWORD(lParam);\n                    SetRect(&g_rcRectangle, g_RectangleAnchor.x, g_RectangleAnchor.y,\n                        g_RectangleAnchor.x, g_RectangleAnchor.y);\n                    OutputDebug( L\"RECTANGLE: %d, %d\\n\", prevPt.x, prevPt.y );\n\n                } else {\n\n                    prevPt.x = LOWORD( lParam );\n                    prevPt.y = HIWORD( lParam );\n                    SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n\n                    Gdiplus::Graphics\tdstGraphics(hdcScreenCursorCompat);\n                    if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n                    {\n                        dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n                    }\n                    Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n                    Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n                    Gdiplus::GraphicsPath path;\n                    pen.SetLineJoin(Gdiplus::LineJoinRound);\n                    path.AddLine(static_cast<INT>(prevPt.x), prevPt.y, prevPt.x, prevPt.y);\n                    dstGraphics.DrawPath(&pen, &path);\n                }\n                InvalidateRect( hWnd, NULL, FALSE );\n\n                // If we're in live zoom, make the drawing pen larger to compensate\n                if( g_ZoomOnLiveZoom && forcePenResize )\n                {\n                    forcePenResize = FALSE;\n\n                    ResizePen( hWnd, hdcScreenCompat, hdcScreenCursorCompat, prevPt, g_Tracing,\n                        &g_Drawing, g_LiveZoomLevel, FALSE, min( static_cast<int>(g_LiveZoomLevel * g_RootPenWidth),\n                        static_cast<int>(g_LiveZoomLevel * MAX_PEN_WIDTH) ) );\n                    OutputDebug( L\"LIVEZOOM_DRAW: zoomLevel: %d rootPenWidth: %d penWidth: %d\\n\",\n                        static_cast<int>(g_LiveZoomLevel), g_RootPenWidth, g_PenWidth );\n                }\n                else if( !g_ZoomOnLiveZoom && forcePenResize )\n                {\n                    forcePenResize = FALSE;\n                    // Scale pen down to root for regular drawing mode\n                    ResizePen( hWnd, hdcScreenCompat, hdcScreenCursorCompat, prevPt, g_Tracing,\n                        &g_Drawing, g_LiveZoomLevel, FALSE, g_RootPenWidth );\n                }\n                g_Drawing = TRUE;\n\n                EnableDisableStickyKeys( FALSE );\n                OutputDebug( L\"LBUTTONDOWN: %d, %d\\n\", prevPt.x, prevPt.y );\n\n                // Constrain the mouse to the visible region\n                boundRc = BoundMouse( zoomLevel, &monInfo, width, height, &cursorPos );\n            }\n        } else if( g_TypeMode != TypeModeOff ) {\n\n            if( !g_HaveTyped ) {\n\n                g_HaveTyped = TRUE;\n\n            } else {\n\n                SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 );\n            }\n        }\n        return TRUE;\n\n    case WM_LBUTTONUP:\n        OutputDebug(L\"LBUTTONUP: zoomed: %d drawing: %d tracing: %d\\n\", \n            g_Zoomed, g_Drawing, g_Tracing);\n\n        if( g_Zoomed && g_Drawing && g_Tracing ) {\n\n            // Are we in pen mode on a tablet?\n            lParam = ScalePenPosition( zoomLevel, &monInfo, boundRc,\n                        message, lParam);\n            OutputDebug(L\"LBUTTONUP: %d, %d\\n\", LOWORD(lParam), HIWORD(lParam));\n            if (lParam == 0) {\n\n                // Drop it\n                break;\n            }\n\n            POINT adjustPos;\n            adjustPos.x = LOWORD(lParam);\n            adjustPos.y = HIWORD(lParam);\n            if( g_StraightDirection == -1 ) {\n\n                adjustPos.x = prevPt.x;\n            \n            } else {\n\n                adjustPos.y = prevPt.y;\n            }\n            lParam = MAKELPARAM( adjustPos.x, adjustPos.y );\t\t\t\t\t\n\n            if( !g_DrawingShape ) {\n\n                Gdiplus::Graphics\tdstGraphics(hdcScreenCompat);\n                if( ( GetWindowLong( g_hWndMain, GWL_EXSTYLE ) & WS_EX_LAYERED ) == 0 )\n                {\n                    dstGraphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);\n                }\n                Gdiplus::Color\tcolor = ColorFromColorRef(g_PenColor);\n                Gdiplus::Pen pen(color, static_cast<Gdiplus::REAL>(g_PenWidth));\n                Gdiplus::GraphicsPath path;\n                pen.SetLineJoin(Gdiplus::LineJoinRound);\n                path.AddLine(prevPt.x, prevPt.y, LOWORD(lParam), HIWORD(lParam));\n                dstGraphics.DrawPath(&pen, &path);\n\n                prevPt.x = LOWORD( lParam );\n                prevPt.y = HIWORD( lParam );\n\n                if ((g_PenColor & 0xFFFFFF) == COLOR_BLUR) {\n\n                    RestoreCursorArea(hdcScreenCompat, hdcScreenCursorCompat, prevPt);\n                }\n                SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n                DrawCursor( hdcScreenCompat, prevPt, zoomLevel, width, height );\n            \n            } else if (g_rcRectangle.top != g_rcRectangle.bottom ||\n                        g_rcRectangle.left != g_rcRectangle.right ) {\n\n                // erase previous\n                SetROP2(hdcScreenCompat, R2_NOTXORPEN); \n                DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle );\n\n                // Draw the final shape\n                HBRUSH hBrush = static_cast<HBRUSH>(GetStockObject( NULL_BRUSH ));\n                HBRUSH oldHbrush = static_cast<HBRUSH>(SelectObject( hdcScreenCompat, hBrush ));\n                SetROP2( hdcScreenCompat, R2_COPYPEN );\n\n                // smooth line\n                if( g_SnapToGrid ) {\n\n                    if( g_DrawingShape == DRAW_LINE ||\n                        g_DrawingShape == DRAW_ARROW ) {\n\n                        if( abs(g_rcRectangle.bottom - g_rcRectangle.top) <\n                            abs(g_rcRectangle.right - g_rcRectangle.left)/10 ) {\n\n                            g_rcRectangle.bottom = g_rcRectangle.top-1;\n                        }\n                        if( abs(g_rcRectangle.right - g_rcRectangle.left) <\n                            abs(g_rcRectangle.bottom - g_rcRectangle.top)/10 ) {\n\n                            g_rcRectangle.right = g_rcRectangle.left-1;\n                        }\n                    }\n                }\n                // Draw final one using Gdi+\n                DrawShape( g_DrawingShape, hdcScreenCompat, &g_rcRectangle, true );\n\n                InvalidateRect( hWnd, NULL, FALSE );\n                DeleteObject( hBrush );\n                SelectObject( hdcScreenCompat, oldHbrush );\n\n                prevPt.x = LOWORD( lParam );\n                prevPt.y = HIWORD( lParam );\n                SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n            }\n            g_Tracing = FALSE;\n            g_DrawingShape = FALSE;\n            OutputDebug( L\"LBUTTONUP:\" );\n        }\n        return TRUE;\n\n    case WM_GETMINMAXINFO:\n\n        reinterpret_cast<MINMAXINFO *>(lParam)->ptMaxSize.x = width;\n        reinterpret_cast<MINMAXINFO*>(lParam)->ptMaxSize.y = height;\n        reinterpret_cast<MINMAXINFO*>(lParam)->ptMaxPosition.x = 0;\n        reinterpret_cast<MINMAXINFO*>(lParam)->ptMaxPosition.y = 0;\n        return TRUE;\n\n    case WM_USER_TYPING_OFF:\t{\n\n        if( g_TypeMode != TypeModeOff ) {\n\n            g_TypeMode = TypeModeOff;\n            ClearTypingCursor( hdcScreenCompat, hdcScreenCursorCompat, cursorRc, g_BlankedScreen );\n            InvalidateRect( hWnd, NULL, FALSE );\n            DeleteTypedText( &typedKeyList );\n\n            // 1 means don't reset the cursor. We get that for font resizing\n            // Only move the cursor if we're drawing, because otherwise the screen moves to center \n            // on the new cursor position\n            if( wParam != 1 && g_Drawing ) {\n\n                prevPt.x = cursorRc.left;\n                prevPt.y = cursorRc.top;\n                SetCursorPos( monInfo.rcMonitor.left + prevPt.x, \n                        monInfo.rcMonitor.top + prevPt.y );\n\n                SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n                SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y ));\n            \n            } else if( !g_Drawing) {\n\n                // FIX: would be nice to reset cursor so screen doesn't move\n                prevPt = textStartPt;\n                SaveCursorArea( hdcScreenCursorCompat, hdcScreenCompat, prevPt );\n                SetCursorPos( prevPt.x, prevPt.y );\n                SendMessage( hWnd, WM_MOUSEMOVE, 0, MAKELPARAM( prevPt.x, prevPt.y ));\n            }\n        }\n        }\n        return TRUE;\n\n    case WM_USER_TRAY_ACTIVATE:\n\n        switch( lParam ) {\n        case WM_RBUTTONUP:\n        case WM_LBUTTONUP:\n        case WM_CONTEXTMENU:\n        {\n            // Set the foreground window so the menu can be closed by clicking elsewhere when\n            // opened via right click, and so keyboard navigation works when opened with the menu\n            // key or Shift-F10.\n            SetForegroundWindow( hWndOptions ? hWndOptions : hWnd );\n\n            // Pop up context menu\n            POINT pt;\n            GetCursorPos( &pt );\n            hPopupMenu = CreatePopupMenu();\n            if(!g_StartedByPowerToys) {\n                // Exiting will happen through disabling in PowerToys, not the context menu.\n                InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDCANCEL, L\"退出(&X)\" );\n                InsertMenu( hPopupMenu, 0, MF_BYPOSITION|MF_SEPARATOR, 0, NULL );\n            }\n            InsertMenu( hPopupMenu, 0, MF_BYPOSITION | ( g_RecordToggle ? MF_CHECKED : 0 ), IDC_RECORD, L\"录屏(&R)\" );\n            InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_ZOOM, L\"放大(&Z)\" );\n            InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_DRAW, L\"画图(&D)\" );\n            InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_BREAK, L\"倒计时(&B)\" );\n            if(!g_StartedByPowerToys) {\n                // When started by PowerToys, options are configured through the PowerToys Settings.\n                InsertMenu( hPopupMenu, 0, MF_BYPOSITION|MF_SEPARATOR, 0, NULL );\n                InsertMenu( hPopupMenu, 0, MF_BYPOSITION, IDC_OPTIONS, L\"设置(&O)\" );\n            }\n            TrackPopupMenu( hPopupMenu, 0, pt.x , pt.y, 0, hWnd, NULL );\n            DestroyMenu( hPopupMenu );\n            break;\n        } \n        case WM_LBUTTONDBLCLK:\n            if( !g_TimerActive ) {\n\n                SendMessage( hWnd, WM_COMMAND, IDC_OPTIONS, 0 );\n            \n            } else {\n\n                SetForegroundWindow( hWnd );\n            }\n            break;\n        }\n        break;\n\n    case WM_USER_STOP_RECORDING:\n        StopRecording();\n        break;\n\n    case WM_USER_SAVE_CURSOR:\n        if( g_Zoomed == TRUE )\n        {\n            GetCursorPos( &savedCursorPos );\n            if( g_Drawing == TRUE )\n            {\n                ClipCursor( NULL );\n            }\n        }\n        break;\n\n    case WM_USER_RESTORE_CURSOR:\n        if( g_Zoomed == TRUE )\n        {\n            if( g_Drawing == TRUE )\n            {\n                boundRc = BoundMouse( zoomLevel, &monInfo, width, height, &cursorPos );\n            }\n            SetCursorPos( savedCursorPos.x, savedCursorPos.y );\n        }\n        break;\n\n    case WM_USER_EXIT_MODE:\n        if( g_Zoomed )\n        {\n            // Turn off\n            if( g_TypeMode != TypeModeOff )\n            {\n                SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 );\n            }\n            else if( !g_Drawing )\n            {\n                // Turn off\n                PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 );\n            }\n            else\n            {\n                if( !g_Tracing )\n                {\n                    RestoreCursorArea( hdcScreenCompat, hdcScreenCursorCompat, prevPt );\n\n                    // Ensure the cursor area is painted before returning\n                    InvalidateRect( hWnd, NULL, FALSE );\n                    UpdateWindow( hWnd );\n\n                    // Make the magnified cursor visible again if LiveDraw is on in LiveZoom\n                    if( GetWindowLong( hWnd, GWL_EXSTYLE ) & WS_EX_LAYERED )\n                    {\n                        if( IsWindowVisible( g_hWndLiveZoom ) )\n                        {\n                            SendMessage( g_hWndLiveZoom, WM_USER_MAGNIFY_CURSOR, TRUE, 0 );\n                        }\n                    }\n                }\n                if( zoomLevel != 1 )\n                {\n                    // Restore the cursor position to prevent moving the view in static zoom\n                    SetCursorPos( monInfo.rcMonitor.left + cursorPos.x, monInfo.rcMonitor.top + cursorPos.y );\n                }\n                g_Drawing = FALSE;\n                g_Tracing = FALSE;\n                EnableDisableStickyKeys( TRUE );\n                SendMessage( hWnd, WM_USER_TYPING_OFF, 0, 0 );\n\n                // Unclip cursor\n                ClipCursor( NULL );\n            }\n        }\n        else if( g_TimerActive )\n        {\n            // Turn off\n            PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 );\n        }\n        break;\n\n    case WM_USER_RELOAD_SETTINGS:\n    {\n        // Reload the settings. This message is called from PowerToys after a setting is changed by the user.\n        reg.ReadRegSettings(RegSettings);\n\n        // Apply tray icon setting\n        EnableDisableTrayIcon(hWnd, g_ShowTrayIcon);\n\n        // This is also called by ZoomIt when it starts and loads the Settings. Opacity is added after loading from registry, so we use the same pattern.\n        if ((g_PenColor >> 24) == 0)\n        {\n            g_PenColor |= 0xFF << 24;\n        }\n\n        // Apply hotkey settings\n        UnregisterAllHotkeys(hWnd);\n        g_ToggleMod = GetKeyMod(g_ToggleKey);\n        g_LiveZoomToggleMod = GetKeyMod(g_LiveZoomToggleKey);\n        g_DrawToggleMod = GetKeyMod(g_DrawToggleKey);\n        g_BreakToggleMod = GetKeyMod(g_BreakToggleKey);\n        g_DemoTypeToggleMod = GetKeyMod(g_DemoTypeToggleKey);\n        g_SnipToggleMod = GetKeyMod(g_SnipToggleKey);\n        g_RecordToggleMod = GetKeyMod(g_RecordToggleKey);\n        BOOL showOptions = FALSE;\n        if (g_ToggleKey)\n        {\n            if (!RegisterHotKey(hWnd, ZOOM_HOTKEY, g_ToggleMod, g_ToggleKey & 0xFF))\n            {\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择放大快捷键。\", APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n        }\n        if (g_LiveZoomToggleKey)\n        {\n            if (!RegisterHotKey(hWnd, LIVE_HOTKEY, g_LiveZoomToggleMod, g_LiveZoomToggleKey & 0xFF) ||\n                !RegisterHotKey(hWnd, LIVE_DRAW_HOTKEY, g_LiveZoomToggleMod ^ MOD_SHIFT, g_LiveZoomToggleKey & 0xFF))\n            {\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择实时放大快捷键。\", APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n        }\n        if (g_DrawToggleKey)\n        {\n            if (!RegisterHotKey(hWnd, DRAW_HOTKEY, g_DrawToggleMod, g_DrawToggleKey & 0xFF))\n            {\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择画图快捷键。\", APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n        }\n        if (g_BreakToggleKey)\n        {\n            if (!RegisterHotKey(hWnd, BREAK_HOTKEY, g_BreakToggleMod, g_BreakToggleKey & 0xFF))\n            {\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择倒计时快捷键。\", APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n        }\n        if (g_DemoTypeToggleKey)\n        {\n            if (!RegisterHotKey(hWnd, DEMOTYPE_HOTKEY, g_DemoTypeToggleMod, g_DemoTypeToggleKey & 0xFF) ||\n                !RegisterHotKey(hWnd, DEMOTYPE_RESET_HOTKEY, (g_DemoTypeToggleMod ^ MOD_SHIFT), g_DemoTypeToggleKey & 0xFF))\n            {\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择自动打字快捷键。\", APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n        }\n        if (g_SnipToggleKey)\n        {\n            if (!RegisterHotKey(hWnd, SNIP_HOTKEY, g_SnipToggleMod, g_SnipToggleKey & 0xFF) ||\n                !RegisterHotKey(hWnd, SNIP_SAVE_HOTKEY, (g_SnipToggleMod ^ MOD_SHIFT), g_SnipToggleKey & 0xFF))\n            {\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择截图快捷键。\", APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n        }\n        if (g_RecordToggleKey)\n        {\n            if (!RegisterHotKey(hWnd, RECORD_HOTKEY, g_RecordToggleMod | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) ||\n                !RegisterHotKey(hWnd, RECORD_CROP_HOTKEY, (g_RecordToggleMod ^ MOD_SHIFT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF) ||\n                !RegisterHotKey(hWnd, RECORD_WINDOW_HOTKEY, (g_RecordToggleMod ^ MOD_ALT) | MOD_NOREPEAT, g_RecordToggleKey & 0xFF))\n            {\n                MessageBox(hWnd, L\"此快捷键已被占用。\\n请重新选择录屏快捷键。\", APPNAME, MB_ICONERROR);\n                showOptions = TRUE;\n            }\n        }\n        if (showOptions)\n        {\n            // To open the PowerToys settings in the ZoomIt page.\n            SendMessage(hWnd, WM_COMMAND, IDC_OPTIONS, 0);\n        }\n        break;\n    }\n    case WM_COMMAND:\n\n        switch(LOWORD( wParam )) {\n\n        case IDC_SAVE_CROP:\n        case IDC_SAVE:\n        {\n            POINT local_savedCursorPos{};\n            if( lParam != SHALLOW_ZOOM )\n            {\n                GetCursorPos(&local_savedCursorPos);\n            }\n\n            HBITMAP     hInterimSaveBitmap;\n            HDC         hInterimSaveDc;\n            HBITMAP     hSaveBitmap;\n            HDC         hSaveDc;\n            int         copyX, copyY;\n            int         copyWidth, copyHeight;\n\n            if ( LOWORD( wParam ) == IDC_SAVE_CROP )\n            {\n                g_RecordCropping = TRUE;\n                SelectRectangle selectRectangle;\n                if( !selectRectangle.Start( hWnd ) )\n                {\n                    g_RecordCropping = FALSE;\n                    if( lParam != SHALLOW_ZOOM )\n                    {\n                        SetCursorPos(local_savedCursorPos.x, local_savedCursorPos.y);\n                    }\n                    break;\n                }\n                auto copyRc = selectRectangle.SelectedRect();\n                selectRectangle.Stop();\n                g_RecordCropping = FALSE;\n                copyX = copyRc.left;\n                copyY = copyRc.top;\n                copyWidth = copyRc.right - copyRc.left;\n                copyHeight = copyRc.bottom - copyRc.top;\n            }\n            else\n            {\n                copyX = 0;\n                copyY = 0;\n                copyWidth = width;\n                copyHeight = height;\n            }\n            OutputDebug( L\"***x: %d, y: %d, width: %d, height: %d\\n\", copyX, copyY, copyWidth, copyHeight );\n\n            RECT oldClipRect{};\n            GetClipCursor( &oldClipRect );\n            ClipCursor( NULL );\n\n            // Capture the screen before displaying the save dialog\n            hInterimSaveDc = CreateCompatibleDC( hdcScreen );\n            hInterimSaveBitmap = CreateCompatibleBitmap( hdcScreen, copyWidth, copyHeight );\n            SelectObject( hInterimSaveDc, hInterimSaveBitmap );\n\n            hSaveDc = CreateCompatibleDC( hdcScreen );\n#if SCALE_HALFTONE\n            SetStretchBltMode( hInterimSaveDc, HALFTONE );\n            SetStretchBltMode( hSaveDc, HALFTONE );\n#else\n            SetStretchBltMode( hInterimSaveDc, COLORONCOLOR );\n            SetStretchBltMode( hSaveDc, COLORONCOLOR );\n#endif\n            StretchBlt( hInterimSaveDc,\n                        0, 0,\n                        copyWidth, copyHeight,\n                        hdcScreen,\n                        monInfo.rcMonitor.left + copyX,\n                        monInfo.rcMonitor.top + copyY,\n                        copyWidth, copyHeight,\n                        SRCCOPY|CAPTUREBLT );\n\n            g_bSaveInProgress = true;\n            memset( &openFileName, 0, sizeof(openFileName ));\n            openFileName.lStructSize       = OPENFILENAME_SIZE_VERSION_400;\n            openFileName.hwndOwner         = hWnd;\n            openFileName.hInstance         = static_cast<HINSTANCE>(g_hInstance);\n            openFileName.nMaxFile          = sizeof(filePath)/sizeof(filePath[0]);\n            openFileName.Flags\t\t\t\t= OFN_LONGNAMES|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT;\n            openFileName.lpstrTitle        = L\"保存图像...\";\n            openFileName.lpstrDefExt       = NULL; // \"*.png\";\n            openFileName.nFilterIndex      = 1;\n            openFileName.lpstrFilter       = L\"压缩尺寸 PNG\\0*.png\\0\"\n                                             //\"Zoomed BMP\\0*.bmp\\0\"\t\n                                             \"原始尺寸 PNG\\0*.png\\0\\0\";\n                                             //\"Actual size BMP\\0*.bmp\\0\\0\";\n            openFileName.lpstrFile\t\t\t= filePath;\n            if( GetSaveFileName( &openFileName ) )\n            {\n                TCHAR targetFilePath[MAX_PATH];\n                _tcscpy( targetFilePath, filePath );\n                if( !_tcsrchr( targetFilePath, '.' ) )\n                {\n                    _tcscat( targetFilePath, L\".png\" );\n                }\n\n                // Save image at screen size\n                if( openFileName.nFilterIndex == 1 )\n                {\n                    SavePng( targetFilePath, hInterimSaveBitmap );\n                }\n                // Save image scaled down to actual size\n                else\n                {\n                    int saveWidth = static_cast<int>( copyWidth / zoomLevel );\n                    int saveHeight = static_cast<int>( copyHeight / zoomLevel );\n\n                    hSaveBitmap = CreateCompatibleBitmap( hdcScreen, saveWidth, saveHeight );\n                    SelectObject( hSaveDc, hSaveBitmap );\n\n                    StretchBlt( hSaveDc,\n                                0, 0,\n                                saveWidth, saveHeight,\n                                hInterimSaveDc,\n                                0,\n                                0,\n                                copyWidth, copyHeight,\n                                SRCCOPY | CAPTUREBLT );\n\t\t\t\t\n                    SavePng( targetFilePath, hSaveBitmap );\n                }\n            }\n            g_bSaveInProgress = false;\n\n            DeleteDC( hInterimSaveDc );\n            DeleteDC( hSaveDc );\n\n            if( lParam != SHALLOW_ZOOM )\n            {\n                SetCursorPos(local_savedCursorPos.x, local_savedCursorPos.y);\n            }\n            ClipCursor( &oldClipRect );\n            break;\n        }\n\n        case IDC_COPY_CROP:\n        case IDC_COPY: {\n            HBITMAP\t\thSaveBitmap;\n            HDC\t\t\thSaveDc;\n            int         copyX, copyY;\n            int         copyWidth, copyHeight;\n\n            if( LOWORD( wParam ) == IDC_COPY_CROP )\n            {\n                g_RecordCropping = TRUE;\n                POINT local_savedCursorPos{};\n                if( lParam != SHALLOW_ZOOM )\n                {\n                    GetCursorPos(&local_savedCursorPos);\n                }\n                SelectRectangle selectRectangle;\n                if( !selectRectangle.Start( hWnd ) )\n                {\n                    g_RecordCropping = FALSE;\n                    break;\n                }\n                auto copyRc = selectRectangle.SelectedRect();\n                selectRectangle.Stop();\n                if( lParam != SHALLOW_ZOOM )\n                {\n                    SetCursorPos(local_savedCursorPos.x, local_savedCursorPos.y);\n                }\n                g_RecordCropping = FALSE;\n\n                copyX = copyRc.left;\n                copyY = copyRc.top;\n                copyWidth = copyRc.right - copyRc.left;\n                copyHeight = copyRc.bottom - copyRc.top;\n            }\n            else\n            {\n                copyX = 0;\n                copyY = 0;\n                copyWidth = width;\n                copyHeight = height;\n            }\n            OutputDebug( L\"***x: %d, y: %d, width: %d, height: %d\\n\", copyX, copyY, copyWidth, copyHeight );\n\n            hSaveBitmap = CreateCompatibleBitmap( hdcScreen, copyWidth, copyHeight );\n            hSaveDc = CreateCompatibleDC( hdcScreen );\n            SelectObject( hSaveDc, hSaveBitmap );\n#if SCALE_HALFTONE\n            SetStretchBltMode( hSaveDc, HALFTONE );\n#else\n            SetStretchBltMode( hSaveDc, COLORONCOLOR );\n#endif\n\t\t\tStretchBlt( hSaveDc,\n                        0, 0,\n                        copyWidth, copyHeight,\n                        hdcScreen,\n                        monInfo.rcMonitor.left + copyX,\n                        monInfo.rcMonitor.top + copyY,\n                        copyWidth, copyHeight,\n                        SRCCOPY|CAPTUREBLT ); \n\n            if( OpenClipboard( hWnd )) {\n            \n                EmptyClipboard();\n                SetClipboardData( CF_BITMAP, hSaveBitmap );\n                CloseClipboard();\n            }\n\n            DeleteDC( hSaveDc );\n            }\n            break;\n\n        case IDC_DRAW: \n            PostMessage( hWnd, WM_HOTKEY, DRAW_HOTKEY, 1 );\n            break;\n\n        case IDC_ZOOM:\n            PostMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 1 );\n            break;\n\n        case IDC_RECORD:\n            PostMessage( hWnd, WM_HOTKEY, RECORD_HOTKEY, 1 );\n            break;\n\n        case IDC_OPTIONS:\n            // Don't show win32 forms options if started by PowerToys.\n            // Show the PowerToys Settings application instead.\n\n            if( g_StartedByPowerToys )\n            {\n#ifdef __ZOOMIT_POWERTOYS__\n                OpenPowerToysSettingsApp();\n#endif // __ZOOMIT_POWERTOYS__\n            }\n            else\n            {\n                DialogBox( g_hInstance, L\"OPTIONS\", hWnd, OptionsProc );\n            }\n            break;\n\n        case IDC_BREAK:\n        {\n            // Manage handles, clean visual transitions, and Options delta\n            if( g_TimerActive )\n            {\n                if( activeBreakShowBackgroundFile != g_BreakShowBackgroundFile ||\n                    activeBreakShowDesktop != g_BreakShowDesktop )\n                {\n                    if( g_BreakShowBackgroundFile && !g_BreakShowDesktop )\n                    {\n                        SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_DESTROY );\n                    }\n                    else\n                    {\n                        SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 );\n                    }\n                }\n                else\n                {\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, SHALLOW_DESTROY );\n                    g_TimerActive = TRUE;\n                }\n            }\n\n            hdcScreen = CreateDC( L\"DISPLAY\", static_cast<PTCHAR>(NULL), static_cast<PTCHAR>(NULL), static_cast<CONST DEVMODE*>(NULL) );\n\n            // toggle second monitor\n            // FIX: we should save whether or not we've switched to a second monitor\n            // rather than just assume that the setting hasn't changed since the break timer\n            // became active\n            if( g_BreakOnSecondary )\n            {\n                EnableDisableSecondaryDisplay( hWnd, TRUE, &secondaryDevMode );\n            }\n\n            // Determine what monitor we're on\n            GetCursorPos( &cursorPos );\n            UpdateMonitorInfo( cursorPos, &monInfo );\n            width = monInfo.rcMonitor.right - monInfo.rcMonitor.left;\n            height = monInfo.rcMonitor.bottom - monInfo.rcMonitor.top;\n\n            // Trigger desktop recapture as necessary when switching monitors\n            if( g_TimerActive && g_BreakShowDesktop && lastMonInfo.rcMonitor != monInfo.rcMonitor )\n            {\n                lastMonInfo = monInfo;\n                SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 );\n                PostMessage( hWnd, WM_COMMAND, IDC_BREAK, 0 );\n                break;\n            }\n            lastMonInfo = monInfo;\n\n            // If the background is a file that hasn't been collected, grab it now\n            if( g_BreakShowBackgroundFile && !g_BreakShowDesktop &&\n                ( !g_TimerActive || wcscmp( activeBreakBackgroundFile, g_BreakBackgroundFile ) ) )\n            {\n                _tcscpy( activeBreakBackgroundFile, g_BreakBackgroundFile );\n                \n                DeleteObject( g_hBackgroundBmp );\n                DeleteDC( g_hDcBackgroundFile );\n                \n                g_hBackgroundBmp = NULL;\n                g_hBackgroundBmp = LoadImageFile( g_BreakBackgroundFile );\n                if( g_hBackgroundBmp == NULL )\n                {\n                    // Clean up hanging handles\n                    SendMessage( hWnd, WM_HOTKEY, ZOOM_HOTKEY, 0 );\n                    ErrorDialog( hWnd, L\"无法加载背景位图\", GetLastError() );\n                    break;\n                }\n                g_hDcBackgroundFile = CreateCompatibleDC( hdcScreen );\n                SelectObject( g_hDcBackgroundFile, g_hBackgroundBmp );\n            }\n            // If the background is a desktop that hasn't been collected, grab it now\n            else if( g_BreakShowBackgroundFile && g_BreakShowDesktop && !g_TimerActive )\n            {\n                g_hBackgroundBmp = CreateFadedDesktopBackground( GetDC(NULL), & monInfo.rcMonitor, NULL );\n                g_hDcBackgroundFile = CreateCompatibleDC( hdcScreen );\n                SelectObject( g_hDcBackgroundFile, g_hBackgroundBmp );\n            }\n\n            // Track Options.Break delta\n            activeBreakShowBackgroundFile = g_BreakShowBackgroundFile;\n            activeBreakShowDesktop = g_BreakShowDesktop;\n\n            g_TimerActive = TRUE;\n#ifdef __ZOOMIT_POWERTOYS__\n            if( g_StartedByPowerToys )\n            {\n                Trace::ZoomItActivateBreak();\n            }\n#endif // __ZOOMIT_POWERTOYS__\n\n            breakTimeout = g_BreakTimeout * 60 + 1;\n\n            // Create font\n            g_LogFont.lfHeight = height / 5;\n            hTimerFont = CreateFontIndirect( &g_LogFont );\n            g_LogFont.lfHeight = height / 8;\n            hNegativeTimerFont = CreateFontIndirect( &g_LogFont );\n\n            // Create backing bitmap\n            hdcScreenCompat = CreateCompatibleDC(hdcScreen); \n            bmp.bmBitsPixel = static_cast<BYTE>(GetDeviceCaps(hdcScreen, BITSPIXEL));\n            bmp.bmPlanes = static_cast<BYTE>(GetDeviceCaps(hdcScreen, PLANES));\n            bmp.bmWidth = width;\n            bmp.bmHeight = height;\n            bmp.bmWidthBytes = ((bmp.bmWidth + 15) &~15)/8; \n            hbmpCompat = CreateBitmap(bmp.bmWidth, bmp.bmHeight, \n                bmp.bmPlanes, bmp.bmBitsPixel, static_cast<CONST VOID *>(NULL)); \n             SelectObject(hdcScreenCompat, hbmpCompat); \n\n            SetTextColor( hdcScreenCompat, g_BreakPenColor );\n            SetBkMode( hdcScreenCompat, TRANSPARENT );\n            SelectObject( hdcScreenCompat, hTimerFont );\n\n            EnableDisableOpacity( hWnd, TRUE );\n            EnableDisableScreenSaver( FALSE );\n\n            SendMessage( hWnd, WM_TIMER, 0, 0 );\n            SetTimer( hWnd, 0, 1000, NULL );\n\n            BringWindowToTop( hWnd );\n            SetForegroundWindow( hWnd );\n            SetActiveWindow( hWnd );\n            SetWindowPos( hWnd, HWND_NOTOPMOST, monInfo.rcMonitor.left, monInfo.rcMonitor.top, \n                    width, height, SWP_SHOWWINDOW );\n        }\n        break;\n\n        case IDCANCEL:\n\n            memset( &tNotifyIconData, 0, sizeof(tNotifyIconData));\n            tNotifyIconData.cbSize = sizeof(NOTIFYICONDATA); \n            tNotifyIconData.hWnd = hWnd; \n            tNotifyIconData.uID = 1; \n            Shell_NotifyIcon(NIM_DELETE, &tNotifyIconData); \n            reg.WriteRegSettings( RegSettings );\n\n            if( hWndOptions )\n            {\n                DestroyWindow( hWndOptions );\n            }\n            DestroyWindow( hWnd );\n            break;\n        }\n        break;\n\n    case WM_TIMER:\n        switch( wParam ) {\n        case 0:\n            //\n            // Break timer\n            //\n            breakTimeout -= 1;\n            InvalidateRect( hWnd, NULL, FALSE );\n            if( breakTimeout == 0 && g_BreakPlaySoundFile ) {\n\n                PlaySound( g_BreakSoundFile, NULL, SND_FILENAME|SND_ASYNC );\n            } \n            break;\n\n        case 2:\n        case 1:\n            //\n            // Telescoping zoom timer\n            //\n            if( zoomTelescopeStep ) {\n\n                zoomLevel *= zoomTelescopeStep;\n                if( (zoomTelescopeStep > 1 && zoomLevel >= zoomTelescopeTarget ) ||\n                    (zoomTelescopeStep < 1 && zoomLevel <= zoomTelescopeTarget )) {\n\n                    zoomLevel = zoomTelescopeTarget;\n                    KillTimer( hWnd, wParam );\n                    OutputDebug( L\"SETCURSOR mon_left: %x mon_top: %x x: %d y: %d\\n\",\n                            monInfo.rcMonitor.left, monInfo.rcMonitor.top, cursorPos.x, cursorPos.y );\n                    SetCursorPos( monInfo.rcMonitor.left + cursorPos.x, \n                                        monInfo.rcMonitor.top + cursorPos.y );\n                } \n\n            } else {\n\n                // Case where we didn't zoom at all\n                KillTimer( hWnd, wParam );\n            }\n            if( wParam == 2 && zoomLevel == 1 ) {\n\n                g_Zoomed = FALSE;\n                if( g_ZoomOnLiveZoom )\n                {\n                    GetCursorPos( &cursorPos );\n                    cursorPos = ScalePointInRects( cursorPos, monInfo.rcMonitor, g_LiveZoomSourceRect );\n                    SetCursorPos( cursorPos.x, cursorPos.y );\n                    SendMessage(hWnd, WM_HOTKEY, LIVE_HOTKEY, 0);\n                }\n                else if( lParam != SHALLOW_ZOOM )\n                {\n                    // Figure out where final unzoomed cursor should be\n                    if (g_Drawing) {\n                        cursorPos = prevPt;\n                    }\n                    OutputDebug(L\"FINAL MOUSE: x: %d y: %d\\n\", cursorPos.x, cursorPos.y );\n                    GetZoomedTopLeftCoordinates(zoomLevel, &cursorPos, &x, width, &y, height);\n                    cursorPos.x = monInfo.rcMonitor.left + x + static_cast<int>((cursorPos.x - x) * zoomLevel);\n                    cursorPos.y = monInfo.rcMonitor.top + y + static_cast<int>((cursorPos.y - y) * zoomLevel);\t\t\n                    SetCursorPos(cursorPos.x, cursorPos.y);\n                }\n                if( hTargetWindow ) {\n\n                    SetWindowPos( hTargetWindow, HWND_BOTTOM, rcTargetWindow.left, rcTargetWindow.top,\n                            rcTargetWindow.right - rcTargetWindow.left, \n                            rcTargetWindow.bottom - rcTargetWindow.top, 0 );\n                    hTargetWindow = NULL;\n                }\n                DeleteDrawUndoList( &drawUndoList );\n\n                // Restore live zoom if we came from that mode\n                if( g_ZoomOnLiveZoom ) {\n\n                    SendMessage( g_hWndLiveZoom, WM_USER_SET_ZOOM, static_cast<WPARAM>(g_LiveZoomLevel), reinterpret_cast<LPARAM>(&g_LiveZoomSourceRect) );\n                    g_ZoomOnLiveZoom = FALSE;\n                    forcePenResize = TRUE;\n                }\n\n                SetForegroundWindow( g_ActiveWindow );\n                ClipCursor( NULL );\n                g_HaveDrawn = FALSE;\n                g_TypeMode = TypeModeOff;\n                g_HaveTyped = FALSE;\n                g_Drawing = FALSE;\n                EnableDisableStickyKeys( TRUE );\n                DeleteObject( hTypingFont );\n                DeleteDC( hdcScreen );\n                DeleteDC( hdcScreenCompat );\n                DeleteDC( hdcScreenCursorCompat );\n                DeleteDC( hdcScreenSaveCompat );\n                DeleteObject( hbmpCompat );\n                DeleteObject( hbmpCursorCompat );\n                DeleteObject( hbmpDrawingCompat );\n                DeleteObject( hDrawingPen );\n\n                SetFocus( g_ActiveWindow );\n                ShowWindow( hWnd, SW_HIDE );\n            }\n            InvalidateRect( hWnd, NULL, FALSE );\n            break;\n\n        case 3:\n            POINT mousePos;\n            GetCursorPos(&mousePos);\n            if (mousePos.x != cursorPos.x || mousePos.y != cursorPos.y)\n            {\n                MONITORINFO monitorInfo = { sizeof(MONITORINFO) };\n                UpdateMonitorInfo(mousePos, &monitorInfo);\n\n                mousePos.x -= monitorInfo.rcMonitor.left;\n                mousePos.y -= monitorInfo.rcMonitor.top;\n\n                OutputDebug(L\"RETRACKING MOUSE: x: %d y: %d\\n\", mousePos.x, mousePos.y);\n                SendMessage(hWnd, WM_MOUSEMOVE, 0, MAKELPARAM(mousePos.x, mousePos.y));\n            }\n            break;\n        }\n        break;\n\n    case WM_PAINT:\n\n        hDc = BeginPaint(hWnd, &ps); \n\n        if( ( ( g_RecordCropping == FALSE ) || ( zoomLevel == 1 ) ) && g_Zoomed ) {\n\n            OutputDebug( L\"PAINT x: %d y: %d width: %d height: %d zoomLevel: %g\\n\",\n                    cursorPos.x, cursorPos.y, width, height, zoomLevel );\n            GetZoomedTopLeftCoordinates( zoomLevel, &cursorPos, &x, width, &y, height );\n#if SCALE_GDIPLUS\n            if ( zoomLevel >= zoomTelescopeTarget )  {\n                // do a high-quality render\n                extern void ScaleImage( HDC hdcDst, float xDst, float yDst, float wDst, float hDst, \n                                        HBITMAP bmSrc, float xSrc, float ySrc, float wSrc, float hSrc );\n\n                ScaleImage( ps.hdc, \n                            0, 0, \n                            (float)bmp.bmWidth, (float)bmp.bmHeight, \n                            hbmpCompat, \n                            (float)x, (float)y, \n                            width/zoomLevel, height/zoomLevel ); \n            } else {\n                // do a fast, less accurate render\n                SetStretchBltMode( hDc, HALFTONE );\n                StretchBlt( ps.hdc, \n                        0, 0, \n                        bmp.bmWidth, bmp.bmHeight, \n                        hdcScreenCompat, \n                        x, y, \n                        (int) (width/zoomLevel), (int) (height/zoomLevel),\n                        SRCCOPY); \n            }\n#else\n#if SCALE_HALFTONE\n            SetStretchBltMode( hDc, zoomLevel == zoomTelescopeTarget ? HALFTONE : COLORONCOLOR );\n#else\n            SetStretchBltMode( hDc, COLORONCOLOR );\n#endif\n            StretchBlt( ps.hdc, \n                    0, 0, \n                    bmp.bmWidth, bmp.bmHeight, \n                    hdcScreenCompat, \n                    x, y, \n                    static_cast<int>(width/zoomLevel), static_cast<int>(height/zoomLevel),\n                    SRCCOPY|CAPTUREBLT ); \n#endif\n        } else if( g_TimerActive ) {\n\n            // Fill bitmap with white\n            rc.top = rc.left = 0;\n            rc.bottom = height;\n            rc.right = width;\n            FillRect( hdcScreenCompat, &rc, GetSysColorBrush( COLOR_WINDOW ));\n\n            // If there's a background bitmap, draw it in the center\n            if( g_hBackgroundBmp ) {\n\n                BITMAP local_bmp;\n                GetObject(g_hBackgroundBmp, sizeof(local_bmp), &local_bmp);\n                SetStretchBltMode( hdcScreenCompat, HALFTONE );\n                if( g_BreakBackgroundStretch ) {\n                    StretchBlt( hdcScreenCompat, 0, 0, width, height,\n                        g_hDcBackgroundFile, 0, 0, local_bmp.bmWidth, local_bmp.bmHeight, SRCCOPY|CAPTUREBLT  );\n                } else {\n                    BitBlt( hdcScreenCompat, width/2 - local_bmp.bmWidth/2, height/2 - local_bmp.bmHeight/2, \n                        local_bmp.bmWidth, local_bmp.bmHeight, g_hDcBackgroundFile, 0, 0, SRCCOPY|CAPTUREBLT  );\n                }\n            }\n\n            // Draw time\n            if( breakTimeout > 0 ) {\n\n                _stprintf( timerText, L\"% 2d:%02d\", breakTimeout/60, breakTimeout % 60 );\n            \n            } else {\n\n                _tcscpy( timerText, L\"0:00\" );\n            }\n            rc.left = rc.top = 0;\n            DrawText( hdcScreenCompat, timerText, -1, &rc, \n                DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_CALCRECT );\n\n            rc1.left = rc1.right = rc1.bottom = rc1.top = 0;\n            if( g_ShowExpiredTime && breakTimeout < 0 ) {\n\n                _stprintf( negativeTimerText, L\"(-% 2d:%02d)\",\n                        -breakTimeout/60, -breakTimeout % 60 );\n                HFONT prevFont = static_cast<HFONT>(SelectObject( hdcScreenCompat, hNegativeTimerFont ));\n                DrawText( hdcScreenCompat, negativeTimerText, -1, &rc1, \n                    DT_NOCLIP|DT_LEFT|DT_NOPREFIX|DT_CALCRECT );\n                SelectObject( hdcScreenCompat, prevFont );\n            }\n\n            // Position time vertically\n            switch( g_BreakTimerPosition ) {\n            case 0:\n            case 1:\n            case 2:\n                rc.top = 50;\n                break;\n            case 3:\n            case 4:\n            case 5:\n                rc.top = (height - (rc.bottom - rc.top))/2;\n                break;\n            case 6:\n            case 7:\n            case 8:\n                rc.top = height - rc.bottom - 50 - rc1.bottom;\n                break;\n            }\n\n            // Position time horizontally\n            switch( g_BreakTimerPosition ) {\n            case 0:\n            case 3:\n            case 6:\n                rc.left = 50;\n                break;\n            case 1:\n            case 4:\n            case 7:\n                rc.left = (width - (rc.right - rc.left))/2;\n                break;\n            case 2:\n            case 5:\n            case 8:\n                rc.left = width - rc.right - 50;\n                break;\n            }\n            rc.bottom += rc.top;\n            rc.right += rc.left;\n\n            DrawText( hdcScreenCompat, timerText, -1, &rc, DT_NOCLIP|DT_LEFT|DT_NOPREFIX );\n\n            if( g_ShowExpiredTime && breakTimeout < 0 ) {\n\n                rc1.top = rc.bottom + 10;\n                rc1.left = rc.left + ((rc.right - rc.left)-(rc1.right-rc1.left))/2;\n                HFONT prevFont = static_cast<HFONT>(SelectObject( hdcScreenCompat, hNegativeTimerFont ));\n                DrawText( hdcScreenCompat, negativeTimerText, -1, &rc1, \n                    DT_NOCLIP|DT_LEFT|DT_NOPREFIX );\n                SelectObject( hdcScreenCompat, prevFont );\n            }\n\n            // Copy to screen\n            BitBlt( ps.hdc, 0, 0, width, height, hdcScreenCompat, 0, 0, SRCCOPY|CAPTUREBLT  );\n        }\n        EndPaint(hWnd, &ps); \n        return TRUE;\n\n    case WM_DESTROY:\n\n        PostQuitMessage( 0 );\n        break;\n\n    default:\n        if( message == wmTaskbarCreated )\n        {\n            if( g_ShowTrayIcon )\n            {\n                EnableDisableTrayIcon( hWnd, TRUE );\n            }\n            return TRUE;\n        }\n       return DefWindowProc(hWnd, message, wParam, lParam );\n    }\n    return 0;\n}\n\n\n//----------------------------------------------------------------------------\n//\n// LiveZoomWndProc\n//\n//----------------------------------------------------------------------------\nLRESULT CALLBACK LiveZoomWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)\n{\n    RECT\t\trc;\n    POINT\t\tcursorPos;\n    static int\twidth, height;\n    static MONITORINFO\tmonInfo;\n    HDC\t\t\thdcScreen;\n#if 0\n    int\t\t\tdelta;\n    BOOLEAN\t\tzoomIn;\n#endif\n    static POINT\tlastCursorPos;\n    POINT\t\t\tadjustedCursorPos, zoomCenterPos;\n    int\t\t\t\tmoveWidth, moveHeight;\n    int\t\t\t\tsourceRectHeight, sourceRectWidth;\n    DWORD\t\t\tcurTickCount;\n    RECT\t\t\tsourceRect{};\n    static RECT\t\tlastSourceRect;\n    static float\tzoomLevel;\n    static float\tzoomTelescopeStep;\n    static float\tzoomTelescopeTarget;\n    static DWORD\tprevZoomStepTickCount = 0;\n    static BOOL\t\tdwmEnabled = FALSE;\n    static BOOLEAN\tstartedInPresentationMode = FALSE;\n    MAGTRANSFORM matrix;\n\n    switch (message)  {\n    case WM_CREATE:\n\n        // Initialize\n        pMagInitialize();\n        if (pDwmIsCompositionEnabled) pDwmIsCompositionEnabled(&dwmEnabled);\n\n        // Create the zoom window\n        if( !g_fullScreenWorkaround ) {\n\n            g_hWndLiveZoomMag = CreateWindowEx( 0,\n                                        WC_MAGNIFIER,\n                                        TEXT(\"MagnifierWindow\"),\n                                        WS_CHILD | MS_SHOWMAGNIFIEDCURSOR | WS_VISIBLE,\n                                        0, 0, 0, 0, hWnd, NULL, g_hInstance, NULL );\n        }\n\n        ShowWindow( hWnd, SW_SHOW );\n        InvalidateRect( g_hWndLiveZoomMag, NULL, TRUE );\n\n        if( !g_fullScreenWorkaround )\n            SetForegroundWindow(static_cast<HWND>(reinterpret_cast<LPCREATESTRUCT>(lParam)->lpCreateParams));\n\n        // If we're not on Win7+, then set a timer to go off two hours from\n        // now\n        if( g_OsVersion < WIN7_VERSION ) {\n\n            startedInPresentationMode = IsPresentationMode();\n            // if we're not in presentation mode, kill ourselves after a timeout\n            if( !startedInPresentationMode ) {\n\n                SetTimer( hWnd, 1, LIVEZOOM_WINDOW_TIMEOUT, NULL );\n            } \n        }\n        break;\n\n    case WM_SHOWWINDOW:\n        if( wParam == TRUE ) {\n\n            // Determine what monitor we're on\n            lastCursorPos.x = -1;\n            hdcScreen\t= GetDC( NULL );\n            GetCursorPos( &cursorPos );\n            UpdateMonitorInfo( cursorPos, &monInfo );\n            width = monInfo.rcMonitor.right - monInfo.rcMonitor.left;\n            height = monInfo.rcMonitor.bottom - monInfo.rcMonitor.top;\n            lastSourceRect.left = lastSourceRect.right = 0;\n            lastSourceRect.right = width;\n            lastSourceRect.bottom = height;\n\n            // Set window size\n            if( !g_fullScreenWorkaround ) {\n\n                SetWindowPos( hWnd, NULL, monInfo.rcMonitor.left, monInfo.rcMonitor.top,\n                    monInfo.rcMonitor.right - monInfo.rcMonitor.left,\n                    monInfo.rcMonitor.bottom - monInfo.rcMonitor.top,\n                    SWP_NOACTIVATE | SWP_NOZORDER );\n                UpdateWindow(hWnd);\n            }\n\n            // Are we coming back from a static zoom that \n            // was started while we were live zoomed?\n            if( g_ZoomOnLiveZoom ) {\n\n                // Force a zoom to 2x without telescope\n                prevZoomStepTickCount = 0;\n                zoomLevel = static_cast<float>(1.9);\n                zoomTelescopeTarget = 2.0;\n                zoomTelescopeStep = 2.0;\n\n            } else {\n\n                zoomTelescopeStep = ZOOM_LEVEL_STEP_IN;\n                zoomTelescopeTarget = g_ZoomLevels[g_SliderZoomLevel];\n\n                prevZoomStepTickCount = 0;\n                if( dwmEnabled ) {\n\n                    zoomLevel = static_cast<float>(1);\n\n                } else {\n\n                    zoomLevel = static_cast<float>(1.9);\n                }\n            }\n            RegisterHotKey( hWnd, 0, MOD_CONTROL, VK_UP );\n            RegisterHotKey( hWnd, 1, MOD_CONTROL, VK_DOWN );\n\n            // Hide hardware cursor\n            if( !g_fullScreenWorkaround )\n                if( pMagShowSystemCursor ) pMagShowSystemCursor( FALSE );\n\n            if( g_RecordToggle )\n                g_RecordingSession->EnableCursorCapture( false );\n\n            GetCursorPos( &lastCursorPos );\n            SetCursorPos( lastCursorPos.x, lastCursorPos.y );\n\n            SendMessage( hWnd, WM_TIMER, 0, 0);\n            SetTimer( hWnd, 0, ZOOM_LEVEL_STEP_TIME, NULL );\n        \n        } else {\n\n            KillTimer( hWnd, 0 );\n\n            if( g_RecordToggle )\n                g_RecordingSession->EnableCursorCapture();\n\n            if( !g_fullScreenWorkaround )\n                if( pMagShowSystemCursor ) pMagShowSystemCursor( TRUE );\n\n            // Reset the timer to expire two hours from now\n            if( g_OsVersion < WIN7_VERSION && !IsPresentationMode()) {\n\n                KillTimer( hWnd, 1 );\n                SetTimer( hWnd, 1, LIVEZOOM_WINDOW_TIMEOUT, NULL );\n            } else {\n\n                DestroyWindow( hWnd );\n            }\n            UnregisterHotKey( hWnd, 0 );\n            UnregisterHotKey( hWnd, 1 );\n        }\n        break;\n\n    case WM_TIMER:\n        switch( wParam ) {\n        case 0: {\n            // if we're cropping, do not move\n            if( g_RecordCropping == TRUE )\n            {\n                // Still redraw to keep the contents live\n                InvalidateRect( g_hWndLiveZoomMag, nullptr, TRUE );\n                break;\n            }\n\n            GetCursorPos(&cursorPos);\n\n            // Reclaim topmost status, to prevent unmagnified menus from remaining in view. \n            memset(&matrix, 0, sizeof(matrix));\n            if( !g_fullScreenWorkaround ) {\n\n                pSetLayeredWindowAttributes( hWnd, 0, 255, LWA_ALPHA );\n                SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0,\n                    SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE);\n                \n                OutputDebug(L\"LIVEZOOM RECLAIM\\n\");\n            }\n\n            sourceRectWidth = lastSourceRect.right - lastSourceRect.left;\n            sourceRectHeight = lastSourceRect.bottom - lastSourceRect.top;\n            moveWidth = sourceRectWidth/LIVEZOOM_MOVE_REGIONS;\n            moveHeight = sourceRectHeight/LIVEZOOM_MOVE_REGIONS;\n            curTickCount = GetTickCount();\n            if( zoomLevel != zoomTelescopeTarget && \n                (prevZoomStepTickCount == 0 || (curTickCount - prevZoomStepTickCount > ZOOM_LEVEL_STEP_TIME)) ) {\n\n                prevZoomStepTickCount = curTickCount;\n                if( (zoomTelescopeStep > 1 && zoomLevel*zoomTelescopeStep >= zoomTelescopeTarget ) ||\n                    (zoomTelescopeStep < 1 && zoomLevel*zoomTelescopeStep <= zoomTelescopeTarget )) {\n\n                    zoomLevel = zoomTelescopeTarget;\n\n                } else {\n\n                    zoomLevel *= zoomTelescopeStep;\n                }\t\t\t\t\n                // Time to exit zoom mode?\n                if( zoomTelescopeTarget == 1 && zoomLevel == 1 ) {\n\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n                    if( g_RecordToggle )\n                        g_LiveZoomLevelOne = true;\n                    else\n#endif\n                    ShowWindow( hWnd, SW_HIDE );\n\n                } else {\n\n                    matrix.v[0][0] = zoomLevel;\n                    matrix.v[0][2] = (static_cast<float>(-lastSourceRect.left) * zoomLevel);\n                    matrix.v[1][1] = zoomLevel;\n                    matrix.v[1][2] = (static_cast<float>(-lastSourceRect.top) * zoomLevel );\n                    matrix.v[2][2] = 1.0f;\n                }\n                \n                //\n                // Pre-adjust for monitor boundary\n                //\n                adjustedCursorPos.x = cursorPos.x - monInfo.rcMonitor.left;\n                adjustedCursorPos.y = cursorPos.y - monInfo.rcMonitor.top;\n                GetZoomedTopLeftCoordinates( zoomLevel, &adjustedCursorPos, reinterpret_cast<int *>(&zoomCenterPos.x), width, \n                                reinterpret_cast<int *>(&zoomCenterPos.y), height );\n\n                //\n                // Add back monitor boundary\n                //\n                zoomCenterPos.x += monInfo.rcMonitor.left + static_cast<LONG>(width/zoomLevel/2);\n                zoomCenterPos.y += monInfo.rcMonitor.top + static_cast<LONG>(height/zoomLevel/2);\n\n            } else {\n\n                int xOffset = cursorPos.x - lastSourceRect.left;\n                int yOffset = cursorPos.y - lastSourceRect.top;\n                zoomCenterPos.x = 0; \n                zoomCenterPos.y = 0; \n                if( xOffset < moveWidth ) \n                    zoomCenterPos.x = lastSourceRect.left + sourceRectWidth/2 - (moveWidth - xOffset);\n                else if( xOffset > moveWidth * (LIVEZOOM_MOVE_REGIONS-1) ) \n                    zoomCenterPos.x = lastSourceRect.left + sourceRectWidth/2 + (xOffset - moveWidth*(LIVEZOOM_MOVE_REGIONS-1));\n                if( yOffset < moveHeight )\n                    zoomCenterPos.y = lastSourceRect.top + sourceRectHeight/2 - (moveHeight - yOffset);\n                else if( yOffset > moveHeight * (LIVEZOOM_MOVE_REGIONS-1) )\n                    zoomCenterPos.y = lastSourceRect.top + sourceRectHeight/2 + (yOffset - moveHeight*(LIVEZOOM_MOVE_REGIONS-1));\n            }\n            if( matrix.v[0][0] || zoomCenterPos.x || zoomCenterPos.y ) {\n                \n                if( zoomCenterPos.y == 0 ) \n                    zoomCenterPos.y = lastSourceRect.top + sourceRectHeight/2;\n                if( zoomCenterPos.x == 0 )\n                    zoomCenterPos.x = lastSourceRect.left + sourceRectWidth/2;\n\n                int zoomWidth = static_cast<int>(width / zoomLevel);\n                int zoomHeight = static_cast<int>(height/ zoomLevel);\n                sourceRect.left = zoomCenterPos.x - zoomWidth / 2;\n                sourceRect.top = zoomCenterPos.y -  zoomHeight / 2;\n\n                // Don't scroll outside desktop area.\n                if (sourceRect.left < monInfo.rcMonitor.left) \n                    sourceRect.left = monInfo.rcMonitor.left;\n                else if (sourceRect.left > monInfo.rcMonitor.right - zoomWidth )\n                    sourceRect.left = monInfo.rcMonitor.right - zoomWidth;\n                sourceRect.right = sourceRect.left + zoomWidth;\n                if (sourceRect.top < monInfo.rcMonitor.top) \n                    sourceRect.top = monInfo.rcMonitor.top;\n                else if (sourceRect.top > monInfo.rcMonitor.bottom - zoomHeight) \n                    sourceRect.top = monInfo.rcMonitor.bottom - zoomHeight;\n                sourceRect.bottom = sourceRect.top + zoomHeight;\n\n                if( g_ZoomOnLiveZoom ) {\n\n                    matrix.v[0][0] = static_cast<float>(1.0);\n                    matrix.v[0][2] = (static_cast<float>(-monInfo.rcMonitor.left));\n\n                    matrix.v[1][1] = static_cast<float>(1.0);\n                    matrix.v[1][2] = (static_cast<float>(-monInfo.rcMonitor.top));\n\n                    matrix.v[2][2] = 1.0f;\n\n                } else if( lastSourceRect.left != sourceRect.left ||\n                    lastSourceRect.top  != sourceRect.top ) {\n\n                    matrix.v[0][0] = zoomLevel;\n                    matrix.v[0][2] = (static_cast<float>(-sourceRect.left) * zoomLevel);\n\n                    matrix.v[1][1] = zoomLevel;\n                    matrix.v[1][2] = (static_cast<float>(-sourceRect.top) * zoomLevel);\n\n                    matrix.v[2][2] = 1.0f;\n                }\n                lastSourceRect = sourceRect;\n            }\n            lastCursorPos = cursorPos;\n\n            // Update source and zoom if necessary\n            if( matrix.v[0][0] ) {\n\n                OutputDebug(L\"LIVEZOOM update\\n\");\n                if( g_fullScreenWorkaround ) {\n\n                    pMagSetFullscreenTransform(zoomLevel, sourceRect.left, sourceRect.top);\n                    pMagSetInputTransform(TRUE, &sourceRect, &monInfo.rcMonitor);\n                }\n                else {\n\n                    pMagSetWindowTransform(g_hWndLiveZoomMag, &matrix);\n                }\n            }\n\n            if( !g_fullScreenWorkaround ) {\n\n                // Force redraw to refresh screen contents\n                InvalidateRect(g_hWndLiveZoomMag, NULL, TRUE);\n            }\n\n            // are we done zooming?\n            if( zoomLevel == 1 ) {\n\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n                if( g_RecordToggle ) {\n\n                    g_LiveZoomLevelOne = true;\n                }\n                else {\n\n#endif\n                if( g_OsVersion < WIN7_VERSION ) {\n\n                    ShowWindow( hWnd, SW_HIDE );\n\n                } else {\n\n                    DestroyWindow( hWnd );\n                }\n            }\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n            }\n#endif\n            }\n            break;\n        case 1: {\n\n            if( !IsWindowVisible( hWnd )) {\n\n                // This is the cached window timeout. If not in presentation mode,\n                // time to exit\n                if( !IsPresentationMode()) {\n\n                    DestroyWindow( hWnd );\n                }\n            } \n            }\n            break;\n        }\n        break;\n\n    case WM_SETTINGCHANGE:\n        if( g_OsVersion < WIN7_VERSION ) {\n\n            if( startedInPresentationMode && !IsPresentationMode()) {\n\n                // Existing presentation mode\n                DestroyWindow( hWnd );\n            \n            } else if( !startedInPresentationMode && IsPresentationMode()) {\n        \n                // Kill the timer if one was configured, because now\n                // we're going to go away when they exit presentation mode\n                KillTimer( hWnd, 1 );\n            }\n        }\n        break;\n\n    case WM_HOTKEY: {\n        float newZoomLevel = zoomLevel;\n        switch( wParam ) {\n        case 0:\n            // zoom in \n            if( newZoomLevel < ZOOM_LEVEL_MAX ) \n                newZoomLevel *= 2;\n            zoomTelescopeStep = ZOOM_LEVEL_STEP_IN;\n            break;\n\n        case 1:\n            if( newZoomLevel > 2 ) \n                newZoomLevel /= 2;\n            else {\n\n                newZoomLevel *= .75; \n                if( newZoomLevel < ZOOM_LEVEL_MIN ) \n                    newZoomLevel = ZOOM_LEVEL_MIN;\n            }\n            zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT;\n            break;\n        }\n        zoomTelescopeTarget = newZoomLevel;\n        if( !dwmEnabled ) {\n\n            zoomLevel = newZoomLevel;\n        }\n        }\n        break;\n\n    // NOTE: keyboard and mouse input actually don't get sent to us at all when in live zoom mode\n    case WM_KEYDOWN:\n        switch( wParam ) {\n        case VK_ESCAPE:\n            zoomTelescopeStep = ZOOM_LEVEL_STEP_OUT;\n            zoomTelescopeTarget = 1.0;\n            if( !dwmEnabled ) {\n\n                zoomLevel = static_cast<float>(1.1);\n            }\n            break;\n\n        case VK_UP:\n            SendMessage( hWnd, WM_MOUSEWHEEL, \n                MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 ? MK_CONTROL: 0, WHEEL_DELTA), 0 );\n            return TRUE;\n\n        case VK_DOWN:\n            SendMessage( hWnd, WM_MOUSEWHEEL, \n                MAKEWPARAM( GetAsyncKeyState( VK_LCONTROL ) != 0 ? MK_CONTROL: 0, -WHEEL_DELTA), 0 );\n            return TRUE;\n        }\n        break;\n    case WM_DESTROY:\n        g_hWndLiveZoom = NULL;\n        break;\n        \n    case WM_SIZE:\n        GetClientRect(hWnd, &rc);\n        SetWindowPos(g_hWndLiveZoomMag, NULL, \n            rc.left, rc.top, rc.right, rc.bottom, 0 );\n        break;\n\n    case WM_USER_GET_ZOOM_LEVEL:\n        return reinterpret_cast<LRESULT>(&zoomLevel);\n\n    case WM_USER_GET_SOURCE_RECT:\n        return reinterpret_cast<LRESULT>(&lastSourceRect);\n\n    case WM_USER_MAGNIFY_CURSOR:\n        {\n            auto style = GetWindowLong( g_hWndLiveZoomMag, GWL_STYLE );\n            if( wParam == TRUE )\n            {\n                style |= MS_SHOWMAGNIFIEDCURSOR;\n            }\n            else\n            {\n                style &= ~MS_SHOWMAGNIFIEDCURSOR;\n            }\n            SetWindowLong( g_hWndLiveZoomMag, GWL_STYLE, style );\n            InvalidateRect( g_hWndLiveZoomMag, nullptr, TRUE );\n            RedrawWindow( hWnd, nullptr, nullptr, RDW_ALLCHILDREN | RDW_UPDATENOW );\n        }\n        break;\n\n    case WM_USER_SET_ZOOM:\n        {\n            if( g_RecordToggle )\n            {\n                g_SelectRectangle.UpdateOwner( hWnd );\n            }\n\n            if( lParam != NULL ) {\n\n                lastSourceRect = *reinterpret_cast<RECT *>(lParam);\n            }\n#if WINDOWS_CURSOR_RECORDING_WORKAROUND\n            if( g_LiveZoomLevelOne ) {\n\n                g_LiveZoomLevelOne = FALSE;\n\n                zoomTelescopeTarget = static_cast<float>(wParam);\n                zoomTelescopeStep = ZOOM_LEVEL_STEP_IN;\n                prevZoomStepTickCount = 0;\n                zoomLevel = 1.0;\n\n                break;\n            }\n#endif\n            zoomLevel = static_cast<float>(wParam);\n            zoomTelescopeTarget = zoomLevel;\n            matrix.v[0][0] = zoomLevel;\n            matrix.v[0][2] = (static_cast<float>(-lastSourceRect.left) * static_cast<float>(wParam));\n\n            matrix.v[1][1] = zoomLevel;\n            matrix.v[1][2] = (static_cast<float>(-lastSourceRect.top) * static_cast<float>(wParam));\n\n            matrix.v[2][2] = 1.0f;\n\n            if( g_fullScreenWorkaround ) {\n\n                pMagSetFullscreenTransform(zoomLevel, lastSourceRect.left, lastSourceRect.top);\n                pMagSetInputTransform(TRUE, &lastSourceRect, &monInfo.rcMonitor);\n            }\n            else {\n\n                pMagSetWindowTransform(g_hWndLiveZoomMag, &matrix);\n            }\n        }\n        break;\n\n    default:\n        return DefWindowProc(hWnd, message, wParam, lParam);\n    }\n    return 0;  \n}\n\n\n//----------------------------------------------------------------------------\n//\n// Wrapper functions for explicit linking to d3d11.dll\n//\n//----------------------------------------------------------------------------\n\nHRESULT __stdcall WrapCreateDirect3D11DeviceFromDXGIDevice(\n    IDXGIDevice\t\t*dxgiDevice,\n    IInspectable\t**graphicsDevice)\n{\n    if( pCreateDirect3D11DeviceFromDXGIDevice == nullptr )\n        return E_NOINTERFACE;\n\n    return pCreateDirect3D11DeviceFromDXGIDevice( dxgiDevice, graphicsDevice );\n}\n\nHRESULT __stdcall WrapCreateDirect3D11SurfaceFromDXGISurface(\n    IDXGISurface\t*dxgiSurface,\n    IInspectable\t**graphicsSurface)\n{\n    if( pCreateDirect3D11SurfaceFromDXGISurface == nullptr )\n        return E_NOINTERFACE;\n\n    return pCreateDirect3D11SurfaceFromDXGISurface( dxgiSurface, graphicsSurface );\n}\n\nHRESULT __stdcall WrapD3D11CreateDevice(\n    IDXGIAdapter\t\t\t*pAdapter,\n    D3D_DRIVER_TYPE\t\t\tDriverType,\n    HMODULE\t\t\t\t\tSoftware,\n    UINT\t\t\t\t\tFlags,\n    const D3D_FEATURE_LEVEL\t*pFeatureLevels,\n    UINT\t\t\t\t\tFeatureLevels,\n    UINT\t\t\t\t\tSDKVersion,\n    ID3D11Device\t\t\t**ppDevice,\n    D3D_FEATURE_LEVEL\t\t*pFeatureLevel,\n    ID3D11DeviceContext\t\t**ppImmediateContext)\n{\n    if( pD3D11CreateDevice == nullptr )\n        return E_NOINTERFACE;\n\n    return pD3D11CreateDevice( pAdapter, DriverType, Software, Flags, pFeatureLevels,\n                FeatureLevels, SDKVersion, ppDevice, pFeatureLevel, ppImmediateContext );\n}\n\n\n//----------------------------------------------------------------------------\n//\n// InitInstance\n//\n//----------------------------------------------------------------------------\nHWND InitInstance( HINSTANCE hInstance, int nCmdShow ) \n{\n    WNDCLASS  wcZoomIt;\n    HWND\t  hWndMain;\n\n    g_hInstance = hInstance;\n\n    // If magnification, set default hotkey for live zoom\n    if( pMagInitialize ) {\n\n        // register live zoom host window\n        wcZoomIt.style          = CS_HREDRAW | CS_VREDRAW;\n        wcZoomIt.lpfnWndProc    = LiveZoomWndProc;\n        wcZoomIt.cbClsExtra     = 0;\n        wcZoomIt.cbWndExtra     = 0;\n        wcZoomIt.hInstance      = hInstance;\n        wcZoomIt.hIcon          = 0; \n        wcZoomIt.hCursor        = LoadCursor(NULL, IDC_ARROW);\n        wcZoomIt.hbrBackground  = NULL;\n        wcZoomIt.lpszMenuName   = NULL;\n        wcZoomIt.lpszClassName  = L\"MagnifierClass\";\n        RegisterClass(&wcZoomIt);\n\n    } else {\n\n        g_LiveZoomToggleKey = 0;\n    }\n\n    wcZoomIt.style = 0;                     \n    wcZoomIt.lpfnWndProc\t= (WNDPROC)MainWndProc; \n    wcZoomIt.cbClsExtra\t\t= 0;              \n    wcZoomIt.cbWndExtra\t\t= 0;              \n    wcZoomIt.hInstance\t\t= hInstance;       wcZoomIt.hIcon\t\t\t= NULL;\n    wcZoomIt.hCursor\t\t= LoadCursor( hInstance, L\"NULLCURSOR\" );\n    wcZoomIt.hbrBackground\t= NULL;\n    wcZoomIt.lpszMenuName\t= NULL;  \n    wcZoomIt.lpszClassName\t= L\"ZoomitClass\";\n    if ( ! RegisterClass(&wcZoomIt) )\n        return FALSE;\n\n    hWndMain = CreateWindowEx( WS_EX_TOOLWINDOW, L\"ZoomitClass\",           \n                    L\"演示工具放大窗口\", \n                    WS_POPUP,\n                    0, 0, \n                    0, 0,\n                    NULL,               \n                    NULL,               \n                    hInstance,          \n                    NULL);\n\n    // If window could not be created, return \"failure\" \n    if (!hWndMain )\n        return NULL;\n\n    // Make the window visible; update its client area; and return \"success\" \n    ShowWindow(hWndMain, SW_HIDE);\n\n    // Add tray icon\n    EnableDisableTrayIcon( hWndMain, g_ShowTrayIcon );\n    return hWndMain;      \n\n} \n\n//----------------------------------------------------------------------------\n//\n// WinMain\n//\n//----------------------------------------------------------------------------\nint APIENTRY wWinMain(_In_ HINSTANCE hInstance, _In_opt_ HINSTANCE hPrevInstance,\n    _In_ PWSTR lpCmdLine, _In_ int nCmdShow )\n{\n    MSG\t\t\t\t\tmsg; \t\n    HACCEL\t\t\t\thAccel;\n\n    if( !ShowEula( APPNAME, NULL, NULL )) return 1;\n\n#ifdef __ZOOMIT_POWERTOYS__\n    if (powertoys_gpo::getConfiguredZoomItEnabledValue() == powertoys_gpo::gpo_rule_configured_disabled)\n    {\n        Logger::warn(L\"Tried to start with a GPO policy setting the utility to always be disabled. Please contact your systems administrator.\");\n        return 1;\n    }\n\n    Shared::Trace::ETWTrace* trace = nullptr;\n    std::wstring pid = std::wstring(lpCmdLine); // The PowerToys pid is the argument to the process.\n    auto mainThreadId = GetCurrentThreadId();\n    if (!pid.empty())\n    {\n        g_StartedByPowerToys = TRUE;\n\n        trace = new Shared::Trace::ETWTrace();\n        Trace::RegisterProvider();\n        trace->UpdateState(true);\n        Trace::ZoomItStarted();\n\n        // Initialize logger\n        LoggerHelpers::init_logger(L\"ZoomIt\", L\"\", LogSettings::zoomItLoggerName);\n\n        ProcessWaiter::OnProcessTerminate(pid, [mainThreadId](int err) {\n            if (err != ERROR_SUCCESS)\n            {\n                Logger::error(L\"Failed to wait for parent process exit. {}\", get_last_error_or_default(err));\n            }\n            else\n            {\n                Logger::trace(L\"PowerToys runner exited.\");\n            }\n\n            Logger::trace(L\"Exiting ZoomIt\");\n            PostThreadMessage(mainThreadId, WM_QUIT, 0, 0);\n        });\n    }\n#endif // __ZOOMIT_POWERTOYS__\n\n\n#ifndef _WIN64\n\n    if(!g_StartedByPowerToys)\n    {\n        // Launch 64-bit version if necessary\n        SetAutostartFilePath();\n        if( RunningOnWin64()) {\n\n            // Record where we are if we're the 32-bit version\n            return Run64bitVersion();\n        }\n    }\n#endif\n\n    // Single instance per desktop\n\n    if( !CreateEvent( NULL, FALSE, FALSE, _T(\"Local\\\\ZoomitActive\"))) {\n\n        CreateEvent( NULL, FALSE, FALSE, _T(\"ZoomitActive\"));\n    }\t\n    if( GetLastError() == ERROR_ALREADY_EXISTS ) {\n        if (g_StartedByPowerToys)\n        {\n            MessageBox(NULL, L\"检测到已经有一个 ZoomIt 演示工具程序正在运行了。\\n无法再启动 PowerToys ZoomIt。\",\n            APPNAME, MB_ICONERROR | MB_SETFOREGROUND);\n            return 1;\n        }\n\n        // Tell the other instance to show the options dialog\n        g_hWndMain = FindWindow( L\"ZoomitClass\", NULL );\n        if( g_hWndMain != NULL ) {\n\n            PostMessage( g_hWndMain, WM_COMMAND, IDC_OPTIONS, 0 );\n            int count = 0;\n            while( count++ < 5 ) {\n\n                HWND local_hWndOptions = FindWindow( NULL, L\"ZoomIt - Sysinternals: www.sysinternals.com\" );\n                if( local_hWndOptions ) {\n\n                    SetForegroundWindow( local_hWndOptions );\n                    SetWindowPos( local_hWndOptions, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE|SWP_NOMOVE|SWP_SHOWWINDOW ); \n                    break;\n                }\n                Sleep( 100 );\n            }\n        }\n        return 0;\n    }\n\n    g_OsVersion = GetVersion() & 0xFFFF;\n\n    // load accelerators\n    hAccel = LoadAccelerators( hInstance, TEXT(\"ACCELERATORS\"));\n\n    if (FAILED(CoInitialize(0)))\n    {\n        return 0;\n    }\n\n    pEnableThemeDialogTexture = (type_pEnableThemeDialogTexture) GetProcAddress( GetModuleHandle( L\"uxtheme.dll\" ),\n                    \"EnableThemeDialogTexture\" );\n    pMonitorFromPoint = (type_MonitorFromPoint) GetProcAddress( LoadLibrarySafe( L\"User32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"MonitorFromPoint\" );\n    pGetMonitorInfo = (type_pGetMonitorInfo) GetProcAddress( LoadLibrarySafe( L\"User32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"GetMonitorInfoA\" );\n    pSHAutoComplete = (type_pSHAutoComplete) GetProcAddress( LoadLibrarySafe(L\"Shlwapi.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"SHAutoComplete\" );\n    pSetLayeredWindowAttributes = (type_pSetLayeredWindowAttributes) GetProcAddress( LoadLibrarySafe(L\"user32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"SetLayeredWindowAttributes\" );\n    pMagSetWindowSource = (type_pMagSetWindowSource) GetProcAddress( LoadLibrarySafe(L\"magnification.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"MagSetWindowSource\" );\n    pGetPointerType = (type_pGetPointerType)GetProcAddress(LoadLibrarySafe(L\"user32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"GetPointerType\" );\n    pGetPointerPenInfo = (type_pGetPointerPenInfo)GetProcAddress(LoadLibrarySafe(L\"user32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"GetPointerPenInfo\" );\n    pMagInitialize = (type_pMagInitialize)GetProcAddress(LoadLibrarySafe(L\"magnification.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"MagInitialize\");\n    pMagSetWindowTransform = (type_pMagSetWindowTransform) GetProcAddress( LoadLibrarySafe(L\"magnification.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"MagSetWindowTransform\" );\n    pMagSetFullscreenTransform = (type_pMagSetFullscreenTransform)GetProcAddress(LoadLibrarySafe(L\"magnification.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"MagSetFullscreenTransform\");\n    pMagSetInputTransform = (type_pMagSetInputTransform)GetProcAddress(LoadLibrarySafe(L\"magnification.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"MagSetInputTransform\");\n    pMagShowSystemCursor = (type_pMagShowSystemCursor)GetProcAddress(LoadLibrarySafe(L\"magnification.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"MagShowSystemCursor\");\n    pMagSetWindowFilterList = (type_pMagSetWindowFilterList)GetProcAddress( LoadLibrarySafe( L\"magnification.dll\", DLL_LOAD_LOCATION_SYSTEM ),\n                    \"MagSetWindowFilterList\" );\n    pSHQueryUserNotificationState = (type_pSHQueryUserNotificationState) GetProcAddress( LoadLibrarySafe(L\"shell32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"SHQueryUserNotificationState\" );\n    pDwmIsCompositionEnabled = (type_pDwmIsCompositionEnabled) GetProcAddress( LoadLibrarySafe(L\"dwmapi.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"DwmIsCompositionEnabled\" );\n    pSetProcessDPIAware = (type_pSetProcessDPIAware) GetProcAddress( LoadLibrarySafe(L\"User32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"SetProcessDPIAware\");\n    pSystemParametersInfoForDpi = (type_pSystemParametersInfoForDpi)GetProcAddress(LoadLibrarySafe(L\"User32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"SystemParametersInfoForDpi\");\n    pGetDpiForWindow = (type_pGetDpiForWindow)GetProcAddress(LoadLibrarySafe(L\"User32.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"GetDpiForWindow\" );\n    pCreateDirect3D11DeviceFromDXGIDevice = (type_pCreateDirect3D11DeviceFromDXGIDevice) GetProcAddress( LoadLibrarySafe(L\"d3d11.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"CreateDirect3D11DeviceFromDXGIDevice\" );\n    pCreateDirect3D11SurfaceFromDXGISurface = (type_pCreateDirect3D11SurfaceFromDXGISurface) GetProcAddress( LoadLibrarySafe(L\"d3d11.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"CreateDirect3D11SurfaceFromDXGISurface\" );\n    pD3D11CreateDevice = (type_pD3D11CreateDevice) GetProcAddress( LoadLibrarySafe(L\"d3d11.dll\", DLL_LOAD_LOCATION_SYSTEM),\n                    \"D3D11CreateDevice\" );\n\n    // Windows Server 2022 (and including Windows 11) introduced a bug where the cursor disappears\n    // in live zoom. Use the full-screen magnifier as a workaround on those versions only. It is\n    // currently impractical as a replacement; it requires calling MagSetInputTransform for all\n    // input to be transformed. Otherwise, some hit-testing is misdirected. MagSetInputTransform\n    // fails without token UI access, which is impractical; it requires copying the executable\n    // under either %ProgramFiles% or %SystemRoot%, which requires elevation.\n    //\n    // TODO: Update the Windows 11 21H2 revision check when the final number is known. Also add a\n    //       check for the Windows Server 2022 revision if that bug (https://task.ms/38611091) is\n    //       fixed.\n    DWORD windowsRevision, windowsBuild = GetWindowsBuild( &windowsRevision );\n    if( ( windowsBuild == BUILD_WINDOWS_SERVER_2022 ) ||\n        ( ( windowsBuild == BUILD_WINDOWS_11_21H2 ) && ( windowsRevision < 829 ) ) ) {\n\n        if( pMagSetFullscreenTransform && pMagSetInputTransform )\n            g_fullScreenWorkaround = TRUE;\n    }\n\n#if 1\n    // Calling this causes Windows to mess with our query of monitor height and width\n    if( pSetProcessDPIAware ) {\n\n        pSetProcessDPIAware();\n    }\n#endif\n    /* Perform initializations that apply to a specific instance */\n    g_hWndMain = InitInstance(hInstance, nCmdShow);\n    if (!g_hWndMain )\n        return FALSE;\n\n#ifdef __ZOOMIT_POWERTOYS__\n    HANDLE m_reload_settings_event_handle = NULL;\n    HANDLE m_exit_event_handle = NULL;\n    std::thread m_event_triggers_thread;\n\n    if( g_StartedByPowerToys ) {\n        // Start a thread to listen to PowerToys Events.\n        m_reload_settings_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::ZOOMIT_REFRESH_SETTINGS_EVENT);\n        m_exit_event_handle = CreateEventW(nullptr, false, false, CommonSharedConstants::ZOOMIT_EXIT_EVENT);\n        if (!m_reload_settings_event_handle || !m_exit_event_handle)\n        {\n            Logger::warn(L\"Failed to create events. {}\", get_last_error_or_default(GetLastError()));\n            return 1;\n        }\n        m_event_triggers_thread = std::thread([&]() {\n            MSG msg;\n            HANDLE event_handles[2] = {m_reload_settings_event_handle, m_exit_event_handle};\n            while (g_running)\n            {\n                DWORD dwEvt = MsgWaitForMultipleObjects(2, event_handles, false, INFINITE, QS_ALLINPUT);\n                if (!g_running)\n                {\n                    break;\n                }\n                switch (dwEvt)\n                {\n                case WAIT_OBJECT_0:\n                {\n                    // Reload Settings Event\n                    Logger::trace(L\"Received a reload settings event.\");\n                    PostMessage(g_hWndMain, WM_USER_RELOAD_SETTINGS, 0, 0);\n                    break;\n                }\n                case WAIT_OBJECT_0 + 1:\n                {\n                    // Exit Event\n                    Logger::trace(L\"Received an exit event.\");\n                    PostMessage(g_hWndMain, WM_QUIT, 0, 0);\n                    break;\n                }\n                case WAIT_OBJECT_0 + 2:\n                    if (PeekMessageW(&msg, nullptr, 0, 0, PM_REMOVE))\n                    {\n                        TranslateMessage(&msg);\n                        DispatchMessageW(&msg);\n                    }\n                    break;\n                default:\n                    break;\n                }\n            }\n        });\n    }\n#endif // __ZOOMIT_POWERTOYS__\n\n    /* Acquire and dispatch messages until a WM_QUIT message is received. */\n    while (GetMessage(&msg,\tNULL, 0, 0 ))  {\n        if( !TranslateAccelerator( g_hWndMain, hAccel, &msg )) {\n            TranslateMessage(&msg);\n            DispatchMessage(&msg);\n        }\n    }\n    int retCode = (int) msg.wParam;\n\n    g_running = FALSE;\n\n#ifdef __ZOOMIT_POWERTOYS__\n    if(g_StartedByPowerToys)\n    {\n        if (trace!=nullptr) {\n            trace->Flush();\n            delete trace;\n        }\n        Trace::UnregisterProvider();\n        // Needed to unblock MsgWaitForMultipleObjects one last time\n        SetEvent(m_reload_settings_event_handle);\n        CloseHandle(m_reload_settings_event_handle);\n        CloseHandle(m_exit_event_handle);\n        m_event_triggers_thread.join();\n    }\n#endif // __ZOOMIT_POWERTOYS__\n\n    return retCode;\n}\n"
  },
  {
    "path": "PowerToys/src/modules/alwaysontop/AlwaysOnTop/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AlwaysOnTop\" xml:space=\"preserve\">\n    <value>AlwaysOnTop</value>\n    <comment>AlwaysOnTop is a product name, keep as is.</comment>\n  </data>\n  <data name=\"System_Foreground_Elevated\" xml:space=\"preserve\">\n    <value>检测到一个以管理员权限运行的窗口，无法将其置顶。</value>\n    <comment>administrator is context of user account.</comment>\n  </data>\n  <data name=\"System_Foreground_Elevated_Learn_More\" xml:space=\"preserve\">\n    <value>了解更多</value>\n  </data>\n  <data name=\"System_Foreground_Elevated_Dialog_Dont_Show_Again\" xml:space=\"preserve\">\n    <value>不再显示</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/awake/Awake/Core/Constants.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nnamespace Awake.Core\n{\n    internal static class Constants\n    {\n        internal const string AppName = \"Awake\";\n        internal const string FullAppName = \"阻止睡眠\"; // 这个 FullAppName 好像也只有悬停显示才用上... //internal const string FullAppName = \"PowerToys \" + AppName;\n        internal const string TrayWindowId = \"Awake.MessageWindow\";\n        internal const string BuildRegistryLocation = @\"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\";\n\n        // PowerToys Awake build code name. Used for exact logging\n        // that does not map to PowerToys broad version schema to pinpoint\n        // internal issues easier.\n        // Format of the build ID is: CODENAME_MMDDYYYY, where MMDDYYYY\n        // is representative of the date when the last change was made before\n        // the pull request is issued.\n        internal const string BuildId = \"TILLSON_11272024\";\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/awake/Awake/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AWAKE_CHECKED\" xml:space=\"preserve\">\n    <value>已选中</value>\n  </data>\n  <data name=\"AWAKE_EXIT\" xml:space=\"preserve\">\n    <value>退出</value>\n  </data>\n  <data name=\"AWAKE_HOURS\" xml:space=\"preserve\">\n    <value>{0} 小时</value>\n    <comment>{0} shouldn't be removed. It will be replaced by a number greater than 1 at runtime by the application. Used for defining a period to keep the PC awake.</comment>\n  </data>\n  <data name=\"AWAKE_KEEP_INDEFINITELY\" xml:space=\"preserve\">\n    <value>无限模式</value>\n    <comment>Keep the system awake forever</comment>\n  </data>\n  <data name=\"AWAKE_KEEP_ON_INTERVAL\" xml:space=\"preserve\">\n    <value>倒计时模式</value>\n    <comment>Keep the system awake for a given time</comment>\n  </data>\n  <data name=\"AWAKE_KEEP_SCREEN_ON\" xml:space=\"preserve\">\n    <value>保持屏幕常亮</value>\n  </data>\n  <data name=\"AWAKE_KEEP_UNTIL_EXPIRATION\" xml:space=\"preserve\">\n    <value>定时关闭模式</value>\n    <comment>Keep the system awake until expiration date and time</comment>\n  </data>\n  <data name=\"AWAKE_MINUTES\" xml:space=\"preserve\">\n    <value>{0} 分钟</value>\n    <comment>{0} shouldn't be removed. It will be replaced by a number greater than 1 at runtime by the application. Used for defining a period to keep the PC awake.</comment>\n  </data>\n  <data name=\"AWAKE_OFF\" xml:space=\"preserve\">\n    <value>关闭</value>\n    <comment>Don't keep the system awake, use the selected system power plan</comment>\n  </data>\n  <data name=\"AWAKE_UNCHECKED\" xml:space=\"preserve\">\n    <value>未选中</value>\n  </data>\n  <data name=\"AWAKE_CMD_HELP_CONFIG_OPTION\" xml:space=\"preserve\">\n    <value>指定 Awake 是否使用 PowerToys 配置文件来管理状态。</value>\n  </data>\n  <data name=\"AWAKE_CMD_HELP_DISPLAY_OPTION\" xml:space=\"preserve\">\n    <value>设定是否保持屏幕常亮。</value>\n  </data>\n  <data name=\"AWAKE_CMD_HELP_EXPIRE_AT_OPTION\" xml:space=\"preserve\">\n    <value>设定阻止睡眠的结束时间，到时间后恢复默认的睡眠与屏幕设置。</value>\n  </data>\n  <data name=\"AWAKE_CMD_HELP_PID_OPTION\" xml:space=\"preserve\">\n    <value>绑定某个进程来控制阻止睡眠功能。当该进程结束时，恢复默认的睡眠与屏幕设置。</value>\n  </data>\n  <data name=\"AWAKE_CMD_HELP_TIME_OPTION\" xml:space=\"preserve\">\n    <value>设定阻止睡眠的持续时长秒数。</value>\n  </data>\n  <data name=\"AWAKE_EXIT_BINDING_HOOK_MESSAGE\" xml:space=\"preserve\">\n    <value>进程绑定挂钩触发退出。</value>\n  </data>\n  <data name=\"AWAKE_EXIT_MESSAGE\" xml:space=\"preserve\">\n    <value>内部终止处理函数触发退出。</value>\n  </data>\n  <data name=\"AWAKE_EXIT_SIGNAL_MESSAGE\" xml:space=\"preserve\">\n    <value>收到结束进程信号，正在确保安全退出...</value>\n  </data>\n  <data name=\"AWAKE_TRAY_TEXT_EXPIRATION\" xml:space=\"preserve\">\n    <value>定时关闭</value>\n  </data>\n  <data name=\"AWAKE_TRAY_TEXT_INDEFINITE\" xml:space=\"preserve\">\n    <value>开启</value>\n  </data>\n  <data name=\"AWAKE_TRAY_TEXT_OFF\" xml:space=\"preserve\">\n    <value>关闭</value>\n  </data>\n  <data name=\"AWAKE_TRAY_TEXT_TIMED\" xml:space=\"preserve\">\n    <value>倒计时关闭</value>\n  </data>\n  <data name=\"AWAKE_LABEL_DAYS\" xml:space=\"preserve\">\n    <value>d</value>\n    <comment>Used to display number of days in the system tray tooltip.</comment>\n  </data>\n  <data name=\"AWAKE_LABEL_HOURS\" xml:space=\"preserve\">\n    <value>h</value>\n    <comment>Used to display number of hours in the system tray tooltip.</comment>\n  </data>\n  <data name=\"AWAKE_LABEL_MINUTES\" xml:space=\"preserve\">\n    <value>m</value>\n    <comment>Used to display number of minutes in the system tray tooltip.</comment>\n  </data>\n  <data name=\"AWAKE_LABEL_SECONDS\" xml:space=\"preserve\">\n    <value>s</value>\n    <comment>Used to display number of seconds in the system tray tooltip.</comment>\n  </data>\n  <data name=\"AWAKE_CMD_PARENT_PID_OPTION\" xml:space=\"preserve\">\n    <value>使用父进程作为绑定目标 - 父进程结束时退出 Awake。</value>\n  </data>\n  <data name=\"AWAKE_TRAY_TEXT_PID_BINDING\" xml:space=\"preserve\">\n    <value>绑定到</value>\n    <comment>Describes the process ID Awake is bound to when running.</comment>\n  </data>\n  <data name=\"AWAKE_SCREEN_ON\" xml:space=\"preserve\">\n    <value>开</value>\n  </data>\n  <data name=\"AWAKE_SCREEN_OFF\" xml:space=\"preserve\">\n    <value>关</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/colorPicker/ColorPickerUI/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Blue_value\" xml:space=\"preserve\">\n    <value>蓝色值</value>\n    <comment>Tool tip that appears when hovering over a textbox that represents the blue HEX value</comment>\n  </data>\n  <data name=\"Cancel\" xml:space=\"preserve\">\n    <value>取消</value>\n    <comment>Cancel button content</comment>\n  </data>\n  <data name=\"Copied_to_clipboard\" xml:space=\"preserve\">\n    <value>复制成功</value>\n    <comment>Message that appears when a user clicked a button that copies the value to the user's clipboard</comment>\n  </data>\n  <data name=\"Copy_to_clipboard\" xml:space=\"preserve\">\n    <value>复制</value>\n    <comment>Tooltip that describes a button that will copy a value to the user's clipboard</comment>\n  </data>\n  <data name=\"cp_editor\" xml:space=\"preserve\">\n    <value>调色板</value>\n    <comment>Do not translate product name</comment>\n  </data>\n  <data name=\"Green_value\" xml:space=\"preserve\">\n    <value>绿色值</value>\n    <comment>Tool tip that appears when hovering over a textbox that represents the green HEX value</comment>\n  </data>\n  <data name=\"Hex_value\" xml:space=\"preserve\">\n    <value>十六进制值</value>\n    <comment>Tool tip that appears when hovering over a textbox that represents the HEX value</comment>\n  </data>\n  <data name=\"Hue_slider\" xml:space=\"preserve\">\n    <value>色相滑块</value>\n    <comment>Tool tip that appears when hovering over a slider that represents the color hue (from HSV)</comment>\n  </data>\n  <data name=\"No_colors_yet\" xml:space=\"preserve\">\n    <value>点击取色按钮抓取颜色</value>\n    <comment>Message that shows when the user launches the window for the first time or when no colors have been selected</comment>\n  </data>\n  <data name=\"Select\" xml:space=\"preserve\">\n    <value>确定</value>\n    <comment>Select button content</comment>\n  </data>\n  <data name=\"Open_settings\" xml:space=\"preserve\">\n    <value>设置</value>\n    <comment>Tooltip that shows that the user can click this button to open PowerToys settings</comment>\n  </data>\n  <data name=\"Pick_color\" xml:space=\"preserve\">\n    <value>取色</value>\n    <comment>Tooltip that shows that the user can click this button to pick a new color</comment>\n  </data>\n  <data name=\"Red_value\" xml:space=\"preserve\">\n    <value>红色值</value>\n    <comment>Tool tip that appears when hovering over a textbox that represents the red HEX value</comment>\n  </data>\n  <data name=\"Remove\" xml:space=\"preserve\">\n    <value>删除</value>\n    <comment>Tooltip that shows that the user can remove an item from a list</comment>\n  </data>\n  <data name=\"Export_by\" xml:space=\"preserve\">\n    <value>导出</value>\n    <comment>Tooltip that shows the user can export the selected items to a file</comment>\n  </data>\n  <data name=\"Export_by_color\" xml:space=\"preserve\">\n    <value>按颜色分组</value>\n    <comment>Tooltip that shows the user can export the selected items grouped by color to a file</comment>\n  </data>\n  <data name=\"Export_by_format\" xml:space=\"preserve\">\n    <value>按格式分组</value>\n    <comment>Tooltip that shows the user can export the selected items grouped by format to a file</comment>\n  </data>\n  <data name=\"Saturation_slider\" xml:space=\"preserve\">\n    <value>饱和度滑块</value>\n    <comment>Tool tip that appears when hovering over a slider that represents the color saturation (from HSV)</comment>\n  </data>\n  <data name=\"Selected_color\" xml:space=\"preserve\">\n    <value>已选颜色</value>\n    <comment>Tooltip that shows the user what the selected color is</comment>\n  </data>\n  <data name=\"Selected_color_helptext\" xml:space=\"preserve\">\n    <value>可以调整这个颜色</value>\n    <comment>Narrator message that describes to the user that this color can be adjusted</comment>\n  </data>\n  <data name=\"Selected_color_tooltip\" xml:space=\"preserve\">\n    <value>调色</value>\n    <comment>Tooltip that shows that the user can adjust this color</comment>\n  </data>\n  <data name=\"Value_slider\" xml:space=\"preserve\">\n    <value>色值滑块</value>\n    <comment>Tool tip that appears when hovering over a slider that represents the color value (from HSV)</comment>\n  </data>\n  <data name=\"Select_color\" xml:space=\"preserve\">\n    <value>选择该颜色</value>\n  </data>\n  <data name=\"Color_Code\" xml:space=\"preserve\">\n    <value>颜色编码</value>\n  </data>\n  <data name=\"Color_History\" xml:space=\"preserve\">\n    <value>取色记录</value>\n  </data>\n  <data name=\"Color_Palette\" xml:space=\"preserve\">\n    <value>调色板</value>\n  </data>\n  <data name=\"Color_Picker_Control\" xml:space=\"preserve\">\n    <value>取色器控制</value>\n  </data>\n  <data name=\"Darker_color\" xml:space=\"preserve\">\n    <value>变暗一点</value>\n  </data>\n  <data name=\"Darkest_color\" xml:space=\"preserve\">\n    <value>更加暗一点</value>\n  </data>\n  <data name=\"Lighter_color\" xml:space=\"preserve\">\n    <value>变亮一点</value>\n  </data>\n  <data name=\"Lightest color\" xml:space=\"preserve\">\n    <value>更加亮一点</value>\n  </data>\n  <data name=\"TEXT_COLOR_WHITE\" xml:space=\"preserve\">\n    <value>白色</value>\n    <comment>White color #FFFFFF 注：颜色参考官译、office内名称，一定程度修改结合日常通用名称。</comment>\n  </data>\n  <data name=\"TEXT_COLOR_BLACK\" xml:space=\"preserve\">\n    <value>黑色</value>\n    <comment>Black color #000000</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LIGHTGRAY\" xml:space=\"preserve\">\n    <value>浅灰</value>\n    <comment>Light gray color #C8C8C8</comment>\n  </data>\n  <data name=\"TEXT_COLOR_GRAY\" xml:space=\"preserve\">\n    <value>灰色</value>\n    <comment>Gray color #878787</comment>\n  </data>\n  <data name=\"TEXT_COLOR_DARKGRAY\" xml:space=\"preserve\">\n    <value>深灰</value>\n    <comment>Dark gray color #3C3C3C</comment>\n  </data>\n  <data name=\"TEXT_COLOR_CORAL\" xml:space=\"preserve\">\n    <value>米色</value>\n    <comment>Coral color #E1D1CE</comment>\n  </data>\n  <data name=\"TEXT_COLOR_ROSE\" xml:space=\"preserve\">\n    <value>玫红</value>\n    <comment>Rose color #FF6699</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LIGHTORANGE\" xml:space=\"preserve\">\n    <value>浅橙</value>\n    <comment>Light orange color #FF9966</comment>\n  </data>\n  <data name=\"TEXT_COLOR_TAN\" xml:space=\"preserve\">\n    <value>茶色</value>\n    <comment>Tan color #996633</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LIGHTYELLOW\" xml:space=\"preserve\">\n    <value>浅黄</value>\n    <comment>Light yellow color #FFFF66</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LIGHTGREEN\" xml:space=\"preserve\">\n    <value>浅绿</value>\n    <comment>Light green color #66FF66</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LIME\" xml:space=\"preserve\">\n    <value>青绿</value>\n    <comment>Lime color #CCFF33</comment>\n  </data>\n  <data name=\"TEXT_COLOR_AQUA\" xml:space=\"preserve\">\n    <value>水绿</value>\n    <comment>Aqua color #00FFFF</comment>\n  </data>\n  <data name=\"TEXT_COLOR_SKYBLUE\" xml:space=\"preserve\">\n    <value>天蓝</value>\n    <comment>Sky blue color #66FFFF</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LIGHTTURQUOISE\" xml:space=\"preserve\">\n    <value>浅青绿</value>\n    <comment>Light turquoise color #66CCFF</comment>\n  </data>\n  <data name=\"TEXT_COLOR_PALEBLUE\" xml:space=\"preserve\">\n    <value>淡蓝</value>\n    <comment>Pale blue color 不可见？ColorNameHelper.cs</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LIGHTBLUE\" xml:space=\"preserve\">\n    <value>浅蓝</value>\n    <comment>Light blue color #CCECFF</comment>\n  </data>\n  <data name=\"TEXT_COLOR_ICEBLUE\" xml:space=\"preserve\">\n    <value>冰蓝</value>\n    <comment>Ice blue color #D8E3EC</comment>\n  </data>\n  <data name=\"TEXT_COLOR_PERIWINKLE\" xml:space=\"preserve\">\n    <value>粉蓝</value>\n    <comment>Periwinkle color #B1B0D1</comment>\n  </data>\n  <data name=\"TEXT_COLOR_LAVENDER\" xml:space=\"preserve\">\n    <value>淡紫</value>\n    <comment>Lavender color #9933FF</comment>\n  </data>\n  <data name=\"TEXT_COLOR_PINK\" xml:space=\"preserve\">\n    <value>粉红</value>\n    <comment>Pink color #FF66CC</comment>\n  </data>\n  <data name=\"TEXT_COLOR_RED\" xml:space=\"preserve\">\n    <value>红色</value>\n    <comment>Red color #FF0000</comment>\n  </data>\n  <data name=\"TEXT_COLOR_ORANGE\" xml:space=\"preserve\">\n    <value>橙色</value>\n    <comment>Orange color #ED8C12</comment>\n  </data>\n  <data name=\"TEXT_COLOR_BROWN\" xml:space=\"preserve\">\n    <value>棕色</value>\n    <comment>Brown color #AF804F</comment>\n  </data>\n  <data name=\"TEXT_COLOR_GOLD\" xml:space=\"preserve\">\n    <value>金色</value>\n    <comment>Gold color #CC9900</comment>\n  </data>\n  <data name=\"TEXT_COLOR_YELLOW\" xml:space=\"preserve\">\n    <value>黄色</value>\n    <comment>Yellow color #FFFF00</comment>\n  </data>\n  <data name=\"TEXT_COLOR_OLIVEGREEN\" xml:space=\"preserve\">\n    <value>橄榄绿</value>\n    <comment>Olive green color #7C8260</comment>\n  </data>\n  <data name=\"TEXT_COLOR_GREEN\" xml:space=\"preserve\">\n    <value>绿色</value>\n    <comment>Green color #33CC33</comment>\n  </data>\n  <data name=\"TEXT_COLOR_BRIGHTGREEN\" xml:space=\"preserve\">\n    <value>翠绿</value>\n    <comment>Bright green color #3CDBC0</comment>\n  </data>\n  <data name=\"TEXT_COLOR_TEAL\" xml:space=\"preserve\">\n    <value>青色</value>\n    <comment>Teal color #00FFCC</comment>\n  </data>\n  <data name=\"TEXT_COLOR_TURQUOISE\" xml:space=\"preserve\">\n    <value>青绿</value>\n    <comment>Turquoise color #33CCFF</comment>\n  </data>\n  <data name=\"TEXT_COLOR_BLUE\" xml:space=\"preserve\">\n    <value>蓝色</value>\n    <comment>Blue color #0000FF</comment>\n  </data>\n  <data name=\"TEXT_COLOR_BLUEGRAY\" xml:space=\"preserve\">\n    <value>蓝灰</value>\n    <comment>Blue gray color #597BA6</comment>\n  </data>\n  <data name=\"TEXT_COLOR_INDIGO\" xml:space=\"preserve\">\n    <value>靛蓝</value>\n    <comment>Indigo color #333399</comment>\n  </data>\n  <data name=\"TEXT_COLOR_PURPLE\" xml:space=\"preserve\">\n    <value>紫色</value>\n    <comment>Purple color #CC00CC</comment>\n  </data>\n  <data name=\"TEXT_COLOR_DARKRED\" xml:space=\"preserve\">\n    <value>深红</value>\n    <comment>Dark red color #A50021</comment>\n  </data>\n  <data name=\"TEXT_COLOR_DARKYELLOW\" xml:space=\"preserve\">\n    <value>深黄</value>\n    <comment>Dark yellow color #808000</comment>\n  </data>\n  <data name=\"TEXT_COLOR_DARKGREEN\" xml:space=\"preserve\">\n    <value>深绿</value>\n    <comment>Dark green color #006600</comment>\n  </data>\n  <data name=\"TEXT_COLOR_DARKTEAL\" xml:space=\"preserve\">\n    <value>深青</value>\n    <comment>Dark teal color #006666</comment>\n  </data>\n  <data name=\"TEXT_COLOR_DARKBLUE\" xml:space=\"preserve\">\n    <value>深蓝</value>\n    <comment>Dark blue color #000066</comment>\n  </data>\n  <data name=\"TEXT_COLOR_DARKPURPLE\" xml:space=\"preserve\">\n    <value>深紫</value>\n    <comment>Dark purple color #660066</comment>\n  </data>\n  <data name=\"TEXT_COLOR_PLUM\" xml:space=\"preserve\">\n    <value>梅红</value>\n    <comment>Plum color #660033</comment>\n  </data>\n  <data name=\"New_Label\" xml:space=\"preserve\">\n    <value>取色</value>\n    <comment>Button label to pick a new color</comment>\n  </data>\n  <data name=\"CP_Title\" xml:space=\"preserve\">\n    <value>取色器</value>\n    <comment>Do not translate product name</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/colorPicker/ColorPickerUI/ViewModels/ColorEditorViewModel.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.ComponentModel.Composition;\nusing System.Globalization;\nusing System.IO;\nusing System.Linq;\nusing System.Windows.Input;\nusing System.Windows.Media;\n\nusing ColorPicker.Common;\nusing ColorPicker.Helpers;\nusing ColorPicker.Models;\nusing ColorPicker.Settings;\nusing ColorPicker.ViewModelContracts;\nusing Microsoft.PowerToys.Settings.UI.Library.Enumerations;\nusing Microsoft.Win32;\n\nnamespace ColorPicker.ViewModels\n{\n    [Export(typeof(IColorEditorViewModel))]\n    public class ColorEditorViewModel : ViewModelBase, IColorEditorViewModel\n    {\n        private readonly IUserSettings _userSettings;\n        private readonly List<ColorFormatModel> _allColorRepresentations = new List<ColorFormatModel>();\n        private Color _selectedColor;\n        private bool _initializing;\n        private int _selectedColorIndex;\n\n        [ImportingConstructor]\n        public ColorEditorViewModel(IUserSettings userSettings)\n        {\n            OpenColorPickerCommand = new RelayCommand(() => OpenColorPickerRequested?.Invoke(this, EventArgs.Empty));\n            OpenSettingsCommand = new RelayCommand(() => OpenSettingsRequested?.Invoke(this, EventArgs.Empty));\n\n            RemoveColorsCommand = new RelayCommand(DeleteSelectedColors);\n            ExportColorsGroupedByColorCommand = new RelayCommand(ExportSelectedColorsByColor);\n            ExportColorsGroupedByFormatCommand = new RelayCommand(ExportSelectedColorsByFormat);\n            SelectedColorChangedCommand = new RelayCommand((newColor) =>\n            {\n                if (ColorsHistory.Contains((Color)newColor))\n                {\n                    ColorsHistory.Remove((Color)newColor);\n                }\n\n                ColorsHistory.Insert(0, (Color)newColor);\n                SelectedColorIndex = 0;\n            });\n            ColorsHistory.CollectionChanged += ColorsHistory_CollectionChanged;\n            _userSettings = userSettings;\n            SetupAllColorRepresentations();\n            SetupAvailableColorRepresentations();\n        }\n\n        public event EventHandler OpenColorPickerRequested;\n\n        public event EventHandler OpenSettingsRequested;\n\n        public ICommand OpenColorPickerCommand { get; }\n\n        public ICommand OpenSettingsCommand { get; }\n\n        public ICommand RemoveColorsCommand { get; }\n\n        public ICommand ExportColorsGroupedByColorCommand { get; }\n\n        public ICommand ExportColorsGroupedByFormatCommand { get; }\n\n        public ICommand SelectedColorChangedCommand { get; }\n\n        public ICommand HideColorFormatCommand { get; }\n\n        public ObservableCollection<Color> ColorsHistory { get; } = new ObservableCollection<Color>();\n\n        public ObservableCollection<ColorFormatModel> ColorRepresentations { get; } = new ObservableCollection<ColorFormatModel>();\n\n        public Color SelectedColor\n        {\n            get\n            {\n                return _selectedColor;\n            }\n\n            set\n            {\n                _selectedColor = value;\n                OnPropertyChanged();\n            }\n        }\n\n        public int SelectedColorIndex\n        {\n            get\n            {\n                return _selectedColorIndex;\n            }\n\n            set\n            {\n                _selectedColorIndex = value;\n                if (value >= 0)\n                {\n                    SelectedColor = ColorsHistory[_selectedColorIndex];\n                }\n\n                OnPropertyChanged();\n            }\n        }\n\n        public void Initialize()\n        {\n            _initializing = true;\n\n            ColorsHistory.Clear();\n\n            foreach (var item in _userSettings.ColorHistory)\n            {\n                var parts = item.Split('|');\n                ColorsHistory.Add(new Color()\n                {\n                    A = byte.Parse(parts[0], NumberStyles.Integer, CultureInfo.InvariantCulture),\n                    R = byte.Parse(parts[1], NumberStyles.Integer, CultureInfo.InvariantCulture),\n                    G = byte.Parse(parts[2], NumberStyles.Integer, CultureInfo.InvariantCulture),\n                    B = byte.Parse(parts[3], NumberStyles.Integer, CultureInfo.InvariantCulture),\n                });\n                SelectedColorIndex = 0;\n            }\n\n            _initializing = false;\n        }\n\n        private void ColorsHistory_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)\n        {\n            if (!_initializing)\n            {\n                _userSettings.ColorHistory.ClearWithoutNotification();\n                foreach (var item in ColorsHistory)\n                {\n                    _userSettings.ColorHistory.AddWithoutNotification(item.A + \"|\" + item.R + \"|\" + item.G + \"|\" + item.B);\n                }\n\n                _userSettings.ColorHistory.ReleaseNotification();\n            }\n        }\n\n        private void DeleteSelectedColors(object selectedColors)\n        {\n            var colorsToRemove = ((IList)selectedColors).OfType<Color>().ToList();\n            var indicesToRemove = colorsToRemove.Select(color => ColorsHistory.IndexOf(color)).ToList();\n\n            foreach (var color in colorsToRemove)\n            {\n                ColorsHistory.Remove(color);\n            }\n\n            SelectedColorIndex = ComputeWhichIndexToSelectAfterDeletion(colorsToRemove.Count + ColorsHistory.Count, indicesToRemove);\n            SessionEventHelper.Event.EditorHistoryColorRemoved = true;\n        }\n\n        private void ExportSelectedColorsByColor(object selectedColors)\n        {\n            ExportColors(selectedColors, GroupExportedColorsBy.Color);\n        }\n\n        private void ExportSelectedColorsByFormat(object selectedColors)\n        {\n            ExportColors(selectedColors, GroupExportedColorsBy.Format);\n        }\n\n        private void ExportColors(object colorsToExport, GroupExportedColorsBy method)\n        {\n            var colors = SerializationHelper.ConvertToDesiredColorFormats((IList)colorsToExport, ColorRepresentations, method);\n\n            var dialog = new SaveFileDialog\n            {\n                Title = \"保存所选颜色\",\n                Filter = \"文本文件 (*.txt)|*.txt|Json 文件 (*.json)|*.json\",\n            };\n\n            if (dialog.ShowDialog() == true)\n            {\n                var extension = Path.GetExtension(dialog.FileName);\n\n                var contentToWrite = extension.ToUpperInvariant() switch\n                {\n                    \".TXT\" => colors.ToTxt(';'),\n                    \".JSON\" => colors.ToJson(),\n                    _ => string.Empty,\n                };\n\n                File.WriteAllText(dialog.FileName, contentToWrite);\n                SessionEventHelper.Event.EditorColorsExported = true;\n            }\n        }\n\n        // Will select the closest color to the last selected one in color history\n        private static int ComputeWhichIndexToSelectAfterDeletion(int colorsCount, List<int> indicesToRemove)\n        {\n            var newIndices = Enumerable.Range(0, colorsCount).ToList();\n            foreach (var index in indicesToRemove)\n            {\n                newIndices[index] = -1;\n            }\n\n            var appearancesOfMinusOne = 0;\n            for (var i = 0; i < newIndices.Count; i++)\n            {\n                if (newIndices[i] < 0)\n                {\n                    appearancesOfMinusOne++;\n                    continue;\n                }\n\n                newIndices[i] -= appearancesOfMinusOne;\n            }\n\n            var lastSelectedIndex = indicesToRemove.Last();\n            for (int i = lastSelectedIndex - 1, j = lastSelectedIndex + 1; ; i--, j++)\n            {\n                if (j < newIndices.Count && newIndices[j] != -1)\n                {\n                    return newIndices[j];\n                }\n\n                if (i >= 0 && newIndices[i] != -1)\n                {\n                    return newIndices[i];\n                }\n\n                if (j >= newIndices.Count && i < 0)\n                {\n                    break;\n                }\n            }\n\n            return -1;\n        }\n\n        private void SetupAllColorRepresentations()\n        {\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.HEX.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.HEX.ToString()).ToLowerInvariant(),\n                });\n\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.RGB.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.RGB.ToString()),\n                });\n\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.HSL.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.HSL.ToString()),\n                });\n\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.HSV.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.HSV.ToString()),\n                });\n\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.CMYK.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.CMYK.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.HSB.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.HSB.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.HSI.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.HSI.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.HWB.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.HWB.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.NCol.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.NCol.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.CIELAB.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.CIELAB.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.CIEXYZ.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.CIEXYZ.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = ColorRepresentationType.VEC4.ToString(),\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, ColorRepresentationType.VEC4.ToString()),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = \"Decimal\",\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, \"Decimal\"),\n                });\n            _allColorRepresentations.Add(\n                new ColorFormatModel()\n                {\n                    FormatName = \"HEX Int\",\n                    Convert = (Color color) => ColorRepresentationHelper.GetStringRepresentationFromMediaColor(color, \"HEX Int\"),\n                });\n\n            _userSettings.VisibleColorFormats.CollectionChanged += VisibleColorFormats_CollectionChanged;\n\n            // Any other custom format to be added here as well that are read from settings\n        }\n\n        private void VisibleColorFormats_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)\n        {\n            SetupAvailableColorRepresentations();\n        }\n\n        private void SetupAvailableColorRepresentations()\n        {\n            ColorRepresentations.Clear();\n\n            foreach (var colorFormat in _userSettings.VisibleColorFormats)\n            {\n                ColorRepresentations.Add(new ColorFormatModel() { FormatName = colorFormat.Key.ToUpperInvariant(), Convert = null, FormatString = colorFormat.Value });\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/fancyzones/FancyZonesLib/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Setting_Description\" xml:space=\"preserve\">\n    <value>Create window layouts to help make multi-tasking easy</value>\n    <comment>this is NOT referring to the operating system.</comment>\n  </data>\n  <data name=\"Setting_Description_ShiftDrag\" xml:space=\"preserve\">\n    <value>Hold Shift key to activate zones while dragging</value>\n    <comment>SHIFT is referring to keyboard key.</comment>\n  </data>\n  <data name=\"Setting_Description_MouseSwitch\" xml:space=\"preserve\">\n    <value>Use a non-primary mouse button to toggle zone activation</value>\n  </data>\n  <data name=\"Setting_Description_Override_Snap_Hotkeys\" xml:space=\"preserve\">\n    <value>Override Windows Snap hotkeys (Win + Arrow) to move windows between zones</value>\n    <comment>Windows is referring to OS. Win is referring to Windows Key, \"Arrow\" is referring to keyboard key.</comment>\n  </data>\n  <data name=\"Setting_Description_Move_Window_Across_Monitors\" xml:space=\"preserve\">\n    <value>Move windows between zones across all monitors when snapping with (Win + Arrow)</value>\n    <comment>windows is referring to the display surfaces like applications, not the OS.  Win is referring to Windows Key, \"Arrow\" is referring to keyboard key.</comment>\n  </data>\n  <data name=\"Setting_Description_Move_Windows_Based_On_Position\" xml:space=\"preserve\">\n    <value>Move windows based on their position when snapping with (Win + Arrow)</value>\n    <comment>windows is referring to the display surfaces like applications, not the OS.  Win is referring to Windows Key, \"Arrow\" is referring to keyboard key.</comment>\n  </data>\n  <data name=\"Setting_Description_DisplayChange_MoveWindows\" xml:space=\"preserve\">\n    <value>Keep windows in their zones when the screen resolution changes</value>\n    <comment>windows is referring to the display surfaces like applications, not the OS.</comment>\n  </data>\n  <data name=\"Setting_Description_ZoneSetChange_MoveWindows\" xml:space=\"preserve\">\n    <value>During zone layout changes, windows assigned to a zone will match new size/positions</value>\n    <comment>windows is referring to the display surfaces like applications, not the OS.</comment>\n  </data>\n  <data name=\"Setting_Description_ZoneSetChange_FlashZones\" xml:space=\"preserve\">\n    <value>Flash zones when the active FancyZones layout changes</value>\n    <comment>Flash refers to blinking the zone so it appears/disappears.  FancyZones is the product name</comment>\n  </data>\n  <data name=\"Setting_Description_Show_Fancy_Zones_On_All_Monitors\" xml:space=\"preserve\">\n    <value>Show zones on all monitors while dragging a window</value>\n  </data>\n  <data name=\"Setting_Description_Span_Zones_Across_Monitors\" xml:space=\"preserve\">\n    <value>Allow zones to span across monitors (all monitors must have the same DPI scaling)</value>\n  </data>\n  <data name=\"Setting_Description_Make_Dragged_Window_Transparent\" xml:space=\"preserve\">\n    <value>Make dragged window transparent</value>\n  </data>\n  <data name=\"Setting_Description_ZoneColor\" xml:space=\"preserve\">\n    <value>Zone inactive color (Default #F5FCFF)</value>\n  </data>\n  <data name=\"Setting_Description_Zone_Border_Color\" xml:space=\"preserve\">\n    <value>Zone border color (Default #FFFFFF)</value>\n  </data>\n  <data name=\"Setting_Description_ZoneHighlightColor\" xml:space=\"preserve\">\n    <value>Zone highlight color (Default #008CFF)</value>\n  </data>\n  <data name=\"Setting_Description_Use_CursorPos_Editor_StartupScreen\" xml:space=\"preserve\">\n    <value>Follow mouse cursor instead of focus when launching editor in a multi-screen environment</value>\n  </data>\n  <data name=\"Setting_Description_AppLastZone_MoveWindows\" xml:space=\"preserve\">\n    <value>Move newly created windows to their last known zone</value>\n    <comment>windows is referring to the display surfaces like applications, not the OS.</comment>\n  </data>\n  <data name=\"Setting_Description_Open_Window_On_Active_Monitor\" xml:space=\"preserve\">\n    <value>Move newly created windows to the current active monitor [EXPERIMENTAL]</value>\n  </data>\n  <data name=\"Setting_Description_RestoreSize\" xml:space=\"preserve\">\n    <value>Restore the original size of windows when unsnapping</value>\n  </data>\n  <data name=\"Setting_Launch_Editor_Label\" xml:space=\"preserve\">\n    <value>Zone configuration</value>\n  </data>\n  <data name=\"Setting_Launch_Editor_Button\" xml:space=\"preserve\">\n    <value>Edit zones</value>\n  </data>\n  <data name=\"Setting_Launch_Editor_Description\" xml:space=\"preserve\">\n    <value>To launch the zone editor, select the Edit zones button below or press the zone editor hotkey anytime</value>\n    <comment>\"Edit zones\" must match value from Setting_Launch_Editor_Button value</comment>\n  </data>\n  <data name=\"Setting_Launch_Editor_Hotkey_Label\" xml:space=\"preserve\">\n    <value>Configure the zone editor hotkey</value>\n  </data>\n  <data name=\"Setting_Window_Switching_Toggle_Label\" xml:space=\"preserve\">\n    <value>Toggle shortcuts for switching between windows in the current zone</value>\n  </data>\n  <data name=\"Setting_Next_Tab_Hotkey_Label\" xml:space=\"preserve\">\n    <value>Shortcut for switching to the next window in the current zone</value>\n  </data>\n  <data name=\"Setting_Prev_Tab_Hotkey_Label\" xml:space=\"preserve\">\n    <value>Shortcut for switching to the previous window in the current zone</value>\n  </data>\n  <data name=\"Setting_Excluded_Apps_Description\" xml:space=\"preserve\">\n    <value>To exclude an application from snapping to zones add its name here (one per line). Excluded apps will react to the Windows Snap regardless of all other settings.</value>\n    <comment>Windows refers to the Operating system</comment>\n  </data>\n  <data name=\"Settings_Highlight_Opacity\" xml:space=\"preserve\">\n    <value>Zone opacity (%)</value>\n    <comment>a zone is a snapping region and can be transparent</comment>\n  </data>\n  <data name=\"FancyZones\" xml:space=\"preserve\">\n    <value>窗口布局</value>\n    <comment>FancyZones is a product name, keep as is.</comment>\n  </data>\n  <data name=\"Cant_Drag_Elevated\" xml:space=\"preserve\">\n    <value>检测到一个以管理员权限运行的软件窗口，窗口布局无法对它进行操作。</value>\n    <comment>administrator is context of user account.</comment>\n  </data>\n  <data name=\"Cant_Drag_Elevated_Learn_More\" xml:space=\"preserve\">\n    <value>了解更多</value>\n  </data>\n  <data name=\"Cant_Drag_Elevated_Dialog_Dont_Show_Again\" xml:space=\"preserve\">\n    <value>不再显示</value>\n  </data>\n  <data name=\"Keyboard_Listener_Error\" xml:space=\"preserve\">\n    <value>无法安装快捷键监听器。</value>\n  </data>\n  <data name=\"Window_Event_Listener_Error\" xml:space=\"preserve\">\n    <value>无法安装 Windows 事件监听器。</value>\n    <comment>Windows refers to the Operating system</comment>\n  </data>\n  <data name=\"Powertoys_FancyZones\" xml:space=\"preserve\">\n    <value>PowerToys - 窗口布局</value>\n    <comment>do not loc.  Both are product names</comment>\n  </data>\n  <data name=\"Span_Across_Zones_Warning\" xml:space=\"preserve\">\n    <value>“允许布局跨显示器” 功能需要所有显示器的 DPI 缩放比例都相同。</value>\n  </data>\n  <data name=\"FancyZones_Data_Error\" xml:space=\"preserve\">\n    <value>窗口布局找不到数据储存路径。请将问题反馈到</value>\n    <comment>\"Report bug to\" will have a URL after. FancyZones is a product name, keep as is.</comment>\n  </data>\n  <data name=\"FancyZones_Editor_Launch_Error\" xml:space=\"preserve\">\n    <value>布局编辑器启动失败。请将问题反馈到</value>\n    <comment>\"Report bug to\" will have a URL after. FancyZones is a product name, keep as is.</comment>\n  </data>\n  <data name=\"FancyZones_Settings_Load_Error\" xml:space=\"preserve\">\n    <value>窗口布局配置加载失败。将使用默认配置。</value>\n    <comment>FancyZones is a product name, keep as is.</comment>\n  </data>\n  <data name=\"FancyZones_Settings_Save_Error\" xml:space=\"preserve\">\n    <value>窗口布局配置保存失败，请过会儿再试。如果仍然不行，请将问题反馈到</value>\n    <comment>\"Report bug to\" will have a URL after. FancyZones is a product name, keep as is.</comment>\n  </data>\n  <data name=\"Setting_Description_QuickLayoutSwitch\" xml:space=\"preserve\">\n    <value>Enable quick layout switch</value>\n  </data>\n  <data name=\"Setting_Description_FlashZonesOnQuickSwitch\" xml:space=\"preserve\">\n    <value>Flash zones when switching layout</value>\n  </data>\n  <data name=\"Setting_Description_System_Theme\" xml:space=\"preserve\">\n    <value>Use system theme</value>\n  </data>\n  <data name=\"Setting_Description_Zone_Number_Color\" xml:space=\"preserve\">\n    <value>Zone number color (Default #000000)</value>\n  </data>\n  <data name=\"Setting_Description_Show_Zone_Number\" xml:space=\"preserve\">\n    <value>Show zone number</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/fancyzones/editor/FancyZonesEditor/Properties/Resources.resx",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Add_zone\" xml:space=\"preserve\">\n    <value>添加布局区</value>\n  </data>\n  <data name=\"New_zone_added\" xml:space=\"preserve\">\n    <value>布局区已添加</value>\n  </data>\n  <data name=\"Apply\" xml:space=\"preserve\">\n    <value>应用</value>\n  </data>\n  <data name=\"Cancel\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"Canvas_Layout_Editor\" xml:space=\"preserve\">\n    <value>区块布局编辑器</value>\n  </data>\n  <data name=\"Grid_Layout_Editor\" xml:space=\"preserve\">\n    <value>网格布局编辑器</value>\n  </data>\n  <data name=\"Crash_Report_Message_Box_Text\" xml:space=\"preserve\">\n    <value>请将问题反馈到</value>\n  </data>\n  <data name=\"Custom\" xml:space=\"preserve\">\n    <value>自定义</value>\n  </data>\n  <data name=\"Custom_Layout_Creator\" xml:space=\"preserve\">\n    <value>自定义布局创建器</value>\n  </data>\n  <data name=\"Distance_adjacent_zones\" xml:space=\"preserve\">\n    <value>激活距离</value>\n    <comment>Distance of when an adjacent zone should light up when the window is close to it</comment>\n  </data>\n  <data name=\"Fancy_Zones_Editor_App_Title\" xml:space=\"preserve\">\n    <value>布局编辑器</value>\n  </data>\n  <data name=\"Fancy_Zones_Main_Editor\" xml:space=\"preserve\">\n    <value>主编辑器</value>\n  </data>\n  <data name=\"Name\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"Save_Apply\" xml:space=\"preserve\">\n    <value>保存并应用</value>\n  </data>\n  <data name=\"Show_Space_Zones\" xml:space=\"preserve\">\n    <value>布局区间隔</value>\n    <comment>// OLD</comment>\n  </data>\n  <data name=\"Space_Around_Zones\" xml:space=\"preserve\">\n    <value>布局区间隔</value>\n  </data>\n  <data name=\"Templates\" xml:space=\"preserve\">\n    <value>模板</value>\n  </data>\n  <data name=\"Zone_Count_Decrement\" xml:space=\"preserve\">\n    <value>布局区数量减</value>\n  </data>\n  <data name=\"Zone_Count_Increment\" xml:space=\"preserve\">\n    <value>布局区数量加</value>\n  </data>\n  <data name=\"Error_Invalid_Arguments\" xml:space=\"preserve\">\n    <value>布局编辑器参数无效。</value>\n  </data>\n  <data name=\"Error_Message_Box_Title\" xml:space=\"preserve\">\n    <value>布局编辑器错误</value>\n  </data>\n  <data name=\"Error_Not_Standalone_App\" xml:space=\"preserve\">\n    <value>布局编辑器不能单独运行，请按快捷键或从设置里打开。</value>\n  </data>\n  <data name=\"Error_Parsing_Device_Info\" xml:space=\"preserve\">\n    <value>解析设备信息数据时出错。</value>\n  </data>\n  <data name=\"Template_Layout_Columns\" xml:space=\"preserve\">\n    <value>列</value>\n  </data>\n  <data name=\"Template_Layout_Focus\" xml:space=\"preserve\">\n    <value>层叠</value>\n  </data>\n  <data name=\"Template_Layout_Grid\" xml:space=\"preserve\">\n    <value>网格</value>\n  </data>\n  <data name=\"Template_Layout_Priority_Grid\" xml:space=\"preserve\">\n    <value>优先级网格</value>\n  </data>\n  <data name=\"Template_Layout_Rows\" xml:space=\"preserve\">\n    <value>行</value>\n  </data>\n  <data name=\"Close\" xml:space=\"preserve\">\n    <value>关闭</value>\n  </data>\n  <data name=\"Error_Applying_Layout\" xml:space=\"preserve\">\n    <value>应用布局时出错</value>\n  </data>\n  <data name=\"Error_Layout_Malformed_Data\" xml:space=\"preserve\">\n    <value>布局 “{0}” 的数据格式错误</value>\n  </data>\n  <data name=\"Error_Loading_Custom_Layouts\" xml:space=\"preserve\">\n    <value>加载自定义布局时出错</value>\n  </data>\n  <data name=\"Error_Persisting_Custom_Layout\" xml:space=\"preserve\">\n    <value>暂留自定义布局时出错</value>\n    <comment>//看了下好像根本没用上，无从考证是保存还是暂留</comment>\n  </data>\n  <data name=\"Error_Serializing_Deleted_Layouts\" xml:space=\"preserve\">\n    <value>序列化已删除的布局时出错</value>\n  </data>\n  <data name=\"Error_Exception_Message_Box_Title\" xml:space=\"preserve\">\n    <value>布局编辑器错误处理程序</value>\n  </data>\n  <data name=\"Error_Report\" xml:space=\"preserve\">\n    <value>请将问题反馈到</value>\n  </data>\n  <data name=\"Error_Monitor_Match_Not_Found\" xml:space=\"preserve\">\n    <value>找不到匹配项 ({0})</value>\n  </data>\n  <data name=\"Reset_Layout\" xml:space=\"preserve\">\n    <value>重置布局</value>\n    <comment>as in Reset to a blank value</comment>\n  </data>\n  <data name=\"Choose_Layout\" xml:space=\"preserve\">\n    <value>请选择布局</value>\n  </data>\n  <data name=\"Choose_layout_type\" xml:space=\"preserve\">\n    <value>创建新的布局</value>\n    <comment>Dialog header that allows the user to select a specific layout type</comment>\n  </data>\n  <data name=\"Create\" xml:space=\"preserve\">\n    <value>创建</value>\n    <comment>Button label that creates a new layout</comment>\n  </data>\n  <data name=\"Create_new_layout\" xml:space=\"preserve\">\n    <value>新建布局</value>\n    <comment>Button label that allows the user to create a new layout</comment>\n  </data>\n  <data name=\"Custom_Layout_Create_New\" xml:space=\"preserve\">\n    <value>自定义布局</value>\n  </data>\n  <data name=\"Delete\" xml:space=\"preserve\">\n    <value>删除</value>\n    <comment>Context menu label that allows the user duplicate a layout</comment>\n  </data>\n  <data name=\"Duplicate\" xml:space=\"preserve\">\n    <value>复制</value>\n    <comment>Context menu label that allows the user duplicate a layout</comment>\n  </data>\n  <data name=\"Edit\" xml:space=\"preserve\">\n    <value>编辑</value>\n    <comment>Context menu label that allows the user edit a layout</comment>\n  </data>\n  <data name=\"Layout_Canvas_Description\" xml:space=\"preserve\">\n    <value>添加独立、可堆叠的布局区，就像窗口那样</value>\n  </data>\n  <data name=\"Layout_Canvas_Title\" xml:space=\"preserve\">\n    <value>区块</value>\n  </data>\n  <data name=\"Layout_Grid_Description\" xml:space=\"preserve\">\n    <value>从屏幕大小的区域切分成网格，作为布局区</value>\n  </data>\n  <data name=\"Layout_Grid_Title\" xml:space=\"preserve\">\n    <value>网格</value>\n  </data>\n  <data name=\"Merge_zones\" xml:space=\"preserve\">\n    <value>合并</value>\n    <comment>Button label that allows the user to merge 2 or more zones together</comment>\n  </data>\n  <data name=\"Monitor\" xml:space=\"preserve\">\n    <value>显示器</value>\n  </data>\n  <data name=\"Settings\" xml:space=\"preserve\">\n    <value>模板设置</value>\n  </data>\n  <data name=\"Delete_Layout_Dialog_Announce\" xml:space=\"preserve\">\n    <value>删除布局对话框。</value>\n  </data>\n  <data name=\"Zone_Name\" xml:space=\"preserve\">\n    <value>布局区</value>\n    <comment>The name of the zones.</comment>\n  </data>\n  <data name=\"Width_Name\" xml:space=\"preserve\">\n    <value>宽度</value>\n    <comment>The name of dimension called width.</comment>\n  </data>\n  <data name=\"Height_Name\" xml:space=\"preserve\">\n    <value>高度</value>\n    <comment>The name of dimension called height.</comment>\n  </data>\n  <data name=\"Resizer_Thumb_Announce\" xml:space=\"preserve\">\n    <value>方向键调整大小，Delete 键删除。</value>\n    <comment>Keys and key means the keyboard keys.</comment>\n  </data>\n  <data name=\"Are_You_Sure\" xml:space=\"preserve\">\n    <value>提示</value>\n  </data>\n  <data name=\"Are_You_Sure_Description\" xml:space=\"preserve\">\n    <value>确定删除此布局吗？</value>\n  </data>\n  <data name=\"Edit_zones\" xml:space=\"preserve\">\n    <value>编辑布局区</value>\n  </data>\n  <data name=\"No_Custom_Layouts_Message\" xml:space=\"preserve\">\n    <value>创建一个属于自己的布局</value>\n  </data>\n  <data name=\"Delete_Zone\" xml:space=\"preserve\">\n    <value>删除布局区</value>\n    <comment>A tooltip on a button that allows the user to delete a zone</comment>\n  </data>\n  <data name=\"Error_Parsing_Data_Title\" xml:space=\"preserve\">\n    <value>编辑器数据解析错误。</value>\n  </data>\n  <data name=\"Error_Parsing_Applied_Layouts_Message\" xml:space=\"preserve\">\n    <value>解析应用的布局时出错。</value>\n  </data>\n  <data name=\"Apply_Layout\" xml:space=\"preserve\">\n    <value>应用布局</value>\n  </data>\n  <data name=\"Save\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"NumberOfZones\" xml:space=\"preserve\">\n    <value>布局区数量</value>\n    <comment>// OLD</comment>\n  </data>\n  <data name=\"Template_Layout_Blank\" xml:space=\"preserve\">\n    <value>空白</value>\n  </data>\n  <data name=\"Create_Custom_From_Template\" xml:space=\"preserve\">\n    <value>创建自定义布局</value>\n  </data>\n  <data name=\"Default_Custom_Layout_Name\" xml:space=\"preserve\">\n    <value>自定义布局</value>\n  </data>\n  <data name=\"MergeDescription\" xml:space=\"preserve\">\n    <value>\n\t拖动选择布局区，然后点击“合并”按钮合并。</value>\n    <comment>Click mouse, hold button down and drag across multiple zones in tool\n// 开头换行，否则最后断开不美观</comment>\n  </data>\n  <data name=\"MergeName\" xml:space=\"preserve\">\n    <value>合并:</value>\n    <comment>Title for concept behind Merging two zones together or removing an zone</comment>\n  </data>\n  <data name=\"KeyboardControlsName\" xml:space=\"preserve\">\n    <value>快捷键:</value>\n  </data>\n  <data name=\"KeyboardControlsDescription\" xml:space=\"preserve\">\n    <value>\n\tCtrl+Tab\t开始选择。\n\tTab\t\t切换选择。\n\tShift+S\t\t切分布局区。\n\tDelete\t\t合并分界线。\n\t方向键\t\t移动分界线。</value>\n  </data>\n  <data name=\"KeyboardControlsDescriptionCanvas\" xml:space=\"preserve\">\n    <value>\n\tCtrl+Tab\t\t开始选择。\n\tTab\t\t\t切换选择。\n\t方向键\t\t\t移动 10 像素。\n\tCtrl+方向键\t\t移动 1 像素。\n\tShift+方向键\t\t拉伸 10 像素（两条边各 5 像素）。\n\tCtrl+Shift+方向键\t拉伸 2 像素（两条边各 1 像素）。</value>\n  </data>\n  <data name=\"SplitterDescription\" xml:space=\"preserve\">\n    <value>\n\t单击切分布局区，按住 Shift 改变切分方向。</value>\n    <comment>A segmenter visual for splitting one item into two.  This would be the vertical line. Shift key is referring to key on keyboard\n// 开头换行，否则最后断开不美观</comment>\n  </data>\n  <data name=\"SplitterName\" xml:space=\"preserve\">\n    <value>切分:</value>\n    <comment>Title for concept: A segmenter visual for splitting one item into two.  This would be the vertical line</comment>\n  </data>\n  <data name=\"QuickKey_Description\" xml:space=\"preserve\">\n    <value>按 Ctrl + Win + Alt + 切换键，切换到此布局</value>\n  </data>\n  <data name=\"Quick_Key_None\" xml:space=\"preserve\">\n    <value>无</value>\n  </data>\n  <data name=\"Number_of_zones\" xml:space=\"preserve\">\n    <value>布局区数量</value>\n  </data>\n  <data name=\"Pixels\" xml:space=\"preserve\">\n    <value>像素</value>\n    <comment>Abbreviation of pixels</comment>\n  </data>\n  <data name=\"QuickKey_Title\" xml:space=\"preserve\">\n    <value>快速切换键</value>\n  </data>\n  <data name=\"Edit_Template\" xml:space=\"preserve\">\n    <value>编辑 “{0}”</value>\n  </data>\n  <data name=\"Edit_Layout_Open_Announce\" xml:space=\"preserve\">\n    <value>已打开</value>\n  </data>\n  <data name=\"Layout_Creation_Announce\" xml:space=\"preserve\">\n    <value>自定义布局创建成功。</value>\n  </data>\n  <data name=\"OpenSettings\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"Error_Parsing_Layout_Hotkeys_Message\" xml:space=\"preserve\">\n    <value>解析布局快捷键时出错。</value>\n  </data>\n  <data name=\"Error_Parsing_Layout_Templates_Message\" xml:space=\"preserve\">\n    <value>解析模板布局时出错。</value>\n  </data>\n  <data name=\"Error_Parsing_Custom_Layouts_Message\" xml:space=\"preserve\">\n    <value>解析自定义布局时出错。</value>\n  </data>\n  <data name=\"Custom_slider_announce\" xml:space=\"preserve\">\n    <value>{0} 滑块，取值范围从 {1} 到 {2} 当前为 {3}。</value>\n  </data>\n  <data name=\"Pixel_Value\" xml:space=\"preserve\">\n    <value>{0} 像素</value>\n  </data>\n  <data name=\"Template_Zone_Count_Value\" xml:space=\"preserve\">\n    <value>{0} 块</value>\n  </data>\n  <data name=\"Zones\" xml:space=\"preserve\">\n    <value>块</value>\n  </data>\n  <data name=\"Default_Layout_Horizontal\" xml:space=\"preserve\">\n    <value>设为横屏默认布局</value>\n  </data>\n  <data name=\"Set_Layout_As_Horizontal_Default\" xml:space=\"preserve\">\n    <value>设置为横屏下的默认布局方式</value>\n  </data>\n  <data name=\"Error_Parsing_Default_Layouts_Message\" xml:space=\"preserve\">\n    <value>无法解析默认布局。</value>\n  </data>\n  <data name=\"Default_Layout_Vertical\" xml:space=\"preserve\">\n    <value>设为竖屏默认布局</value>\n  </data>\n  <data name=\"Set_Layout_As_Vertical_Default\" xml:space=\"preserve\">\n    <value>设置为竖屏下的默认布局方式</value>\n  </data>\n  <data name=\"Error_Parsing_Editor_Parameters_Message\" xml:space=\"preserve\">\n    <value>解析编辑器参数时出现错误。</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/imageresizer/ImageResizerContextMenu/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ImageResizer_Context_Menu_Entry\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n  </data>\n  <data name=\"ImageResizer_App_Name\" xml:space=\"preserve\">\n    <value>Image Resizer</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/imageresizer/dll/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ImageResizer_Context_Menu_Entry\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n  </data>\n  <data name=\"ImageResizer_Context_Menu_Entry_Here\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n  </data>\n  <data name=\"ImageResizer\" xml:space=\"preserve\">\n    <value>Image Resizer</value>\n  </data>\n  <data name=\"Settings_Description\" xml:space=\"preserve\">\n    <value>A Windows Shell extension for bulk image resizing.</value>\n  </data>\n  <data name=\"Settings_Header\" xml:space=\"preserve\">\n    <value>Settings can be accessed from within Image Resizer.</value>\n  </data>\n  <data name=\"Settings_Header_Description\" xml:space=\"preserve\">\n    <value>Settings header for Image Resizer</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/imageresizer/ui/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AllFilesFilter\" xml:space=\"preserve\">\n    <value>所有文件</value>\n  </data>\n  <data name=\"Cancel\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"Height\" xml:space=\"preserve\">\n    <value>图片高度</value>\n  </data>\n  <data name=\"ImageResizer\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n    <comment>Product name, do not loc</comment>\n  </data>\n  <data name=\"Input_Auto\" xml:space=\"preserve\">\n    <value>（自动）</value>\n  </data>\n  <data name=\"Input_Content\" xml:space=\"preserve\">\n    <value>选择尺寸预设</value>\n  </data>\n  <data name=\"Input_Custom\" xml:space=\"preserve\">\n    <value>自定义</value>\n  </data>\n  <data name=\"Input_IgnoreOrientation\" xml:space=\"preserve\">\n    <value>自适应图像长宽方向(_O)</value>\n  </data>\n  <data name=\"Input_GifWarning\" xml:space=\"preserve\">\n    <value>GIF 动画可能无法裁剪。</value>\n  </data>\n  <data name=\"Input_Replace\" xml:space=\"preserve\">\n    <value>覆盖原图(_E)</value>\n  </data>\n  <data name=\"Input_Resize\" xml:space=\"preserve\">\n    <value>执行</value>\n  </data>\n  <data name=\"Input_ShrinkOnly\" xml:space=\"preserve\">\n    <value>不执行放大操作(_M)</value>\n  </data>\n  <data name=\"Large\" xml:space=\"preserve\">\n    <value>大号</value>\n  </data>\n  <data name=\"Medium\" xml:space=\"preserve\">\n    <value>中号</value>\n  </data>\n  <data name=\"OK\" xml:space=\"preserve\">\n    <value>确定</value>\n  </data>\n  <data name=\"OK_Tooltip\" xml:space=\"preserve\">\n    <value>应用设置</value>\n  </data>\n  <data name=\"Phone\" xml:space=\"preserve\">\n    <value>省流</value>\n  </data>\n  <data name=\"PictureFilter\" xml:space=\"preserve\">\n    <value>所有图片文件</value>\n  </data>\n  <data name=\"PngInterlaceOption_Default\" xml:space=\"preserve\">\n    <value>（默认）</value>\n  </data>\n  <data name=\"PngInterlaceOption_Off\" xml:space=\"preserve\">\n    <value>关</value>\n  </data>\n  <data name=\"PngInterlaceOption_On\" xml:space=\"preserve\">\n    <value>开</value>\n  </data>\n  <data name=\"Progress_MainInstruction\" xml:space=\"preserve\">\n    <value>操作中……</value>\n  </data>\n  <data name=\"Progress_Stop\" xml:space=\"preserve\">\n    <value>停止</value>\n  </data>\n  <data name=\"Progress_TimeRemaining_HourMinute\" xml:space=\"preserve\">\n    <value>剩余 {0} 小时 {1} 分。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_HourMinutes\" xml:space=\"preserve\">\n    <value>剩余 {0} 小时 {1} 分。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_HoursMinute\" xml:space=\"preserve\">\n    <value>剩余 {0} 小时 {1} 分。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_HoursMinutes\" xml:space=\"preserve\">\n    <value>剩余 {0} 小时 {1} 分。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_MinuteSecond\" xml:space=\"preserve\">\n    <value>剩余 {1} 分 {2} 秒。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_MinuteSeconds\" xml:space=\"preserve\">\n    <value>剩余 {1} 分 {2} 秒。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_MinutesSecond\" xml:space=\"preserve\">\n    <value>剩余 {1} 分 {2} 秒。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_MinutesSeconds\" xml:space=\"preserve\">\n    <value>剩余 {1} 分 {2} 秒。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_Second\" xml:space=\"preserve\">\n    <value>剩余 {2} 秒。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"Progress_TimeRemaining_Seconds\" xml:space=\"preserve\">\n    <value>剩余 {2} 秒。</value>\n    <comment>\"About\" = Approximately, not \"on the subject of\"</comment>\n  </data>\n  <data name=\"ResizeFit_Fill\" xml:space=\"preserve\">\n    <value>填充</value>\n  </data>\n  <data name=\"ResizeFit_Fill_ThirdPersonSingular\" xml:space=\"preserve\">\n    <value>填充到</value>\n  </data>\n  <data name=\"ResizeFit_Fit\" xml:space=\"preserve\">\n    <value>缩放</value>\n  </data>\n  <data name=\"ResizeFit_Fit_ThirdPersonSingular\" xml:space=\"preserve\">\n    <value>缩放到</value>\n  </data>\n  <data name=\"ResizeFit_Stretch\" xml:space=\"preserve\">\n    <value>拉伸</value>\n  </data>\n  <data name=\"ResizeFit_Stretch_ThirdPersonSingular\" xml:space=\"preserve\">\n    <value>拉伸到</value>\n  </data>\n  <data name=\"ResizeUnit_Centimeter\" xml:space=\"preserve\">\n    <value>厘米</value>\n  </data>\n  <data name=\"ResizeUnit_Inch\" xml:space=\"preserve\">\n    <value>英寸</value>\n  </data>\n  <data name=\"ResizeUnit_Percent\" xml:space=\"preserve\">\n    <value>百分比</value>\n  </data>\n  <data name=\"ResizeUnit_Pixel\" xml:space=\"preserve\">\n    <value>像素</value>\n  </data>\n  <data name=\"Resize_Tooltip\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n  </data>\n  <data name=\"Resize_Type\" xml:space=\"preserve\">\n    <value>操作</value>\n  </data>\n  <data name=\"Results_Close\" xml:space=\"preserve\">\n    <value>关闭</value>\n  </data>\n  <data name=\"Results_MainInstruction\" xml:space=\"preserve\">\n    <value>图片调整大小失败</value>\n  </data>\n  <data name=\"Small\" xml:space=\"preserve\">\n    <value>小号</value>\n  </data>\n  <data name=\"Unit\" xml:space=\"preserve\">\n    <value>单位</value>\n  </data>\n  <data name=\"ValueMustBeBetween\" xml:space=\"preserve\">\n    <value>数值必须介于 '{0}' 和 '{1}' 之间。</value>\n  </data>\n  <data name=\"Version\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"Width\" xml:space=\"preserve\">\n    <value>图片宽度</value>\n  </data>\n  <data name=\"Open_settings\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"Input_RemoveMetadata\" xml:space=\"preserve\">\n    <value>删除图片元数据(_D)</value>\n  </data>\n  <data name=\"Image_Sizes\" xml:space=\"preserve\">\n    <value>图像尺寸预设</value>\n  </data>\n  <data name=\"Input_ShrinkOnly.Content\" xml:space=\"preserve\">\n    <value>不执行放大操作(_M)</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/imageresizer/ui/Views/EnumValueConverter.cs",
    "content": "﻿#pragma warning disable IDE0073\n// Copyright (c) Brice Lambson\n// The Brice Lambson licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n// Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/\n#pragma warning restore IDE0073\n\nusing System;\nusing System.Globalization;\nusing System.Text;\nusing System.Windows.Data;\n\nusing ImageResizer.Properties;\n\nnamespace ImageResizer.Views\n{\n    [ValueConversion(typeof(Enum), typeof(string))]\n    public class EnumValueConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            var type = value?.GetType();\n            if (!type.IsEnum)\n            {\n                return value;\n            }\n\n            var builder = new StringBuilder();\n\n            builder\n                .Append(type.Name)\n                .Append('_')\n                .Append(Enum.GetName(type, value));\n\n            var toLower = false;\n            var replacePercentage = false;\n            if ((string)parameter == \"ToLower\")\n            {\n                toLower = true;\n            }\n            else if ((string)parameter == \"ToLower2\")\n            {\n                toLower = true;\n                replacePercentage = true;\n            }\n            else if (parameter != null)\n            {\n                builder\n                    .Append('_')\n                    .Append(parameter);\n            }\n\n            // Fixes #16792 - Looks like culture defaults to en-US, so wrong resource is being fetched.\n#pragma warning disable CA1304 // Specify CultureInfo\n            var targetValue = Resources.ResourceManager.GetString(builder.ToString());\n#pragma warning restore CA1304 // Specify CultureInfo\n\n            if (toLower)\n            {\n                targetValue = targetValue.ToLower(culture);\n            }\n\n            if (replacePercentage)\n            {\n                targetValue = targetValue.Replace(\"百分比\", \"%\");\n            }\n\n            return targetValue;\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n            => value;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/imageresizer/ui/Views/InputPage.xaml",
    "content": "﻿<UserControl\n    x:Class=\"ImageResizer.Views.InputPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:m=\"clr-namespace:ImageResizer.Models\"\n    xmlns:p=\"clr-namespace:ImageResizer.Properties\"\n    xmlns:ui=\"http://schemas.lepo.co/wpfui/2022/xaml\">\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <!--  ComboBox  -->\n            <RowDefinition Height=\"*\" />\n            <!--  other controls  -->\n        </Grid.RowDefinitions>\n\n        <ComboBox\n            Name=\"SizeComboBox\"\n            Grid.Row=\"0\"\n            Height=\"64\"\n            Margin=\"16\"\n            HorizontalAlignment=\"Stretch\"\n            VerticalAlignment=\"Stretch\"\n            VerticalContentAlignment=\"Stretch\"\n            AutomationProperties.Name=\"{x:Static p:Resources.Image_Sizes}\"\n            ItemsSource=\"{Binding Settings.AllSizes}\"\n            SelectedIndex=\"{Binding Settings.SelectedSizeIndex}\">\n            <ComboBox.Resources>\n                <DataTemplate DataType=\"{x:Type m:ResizeSize}\">\n                    <Grid VerticalAlignment=\"Center\" AutomationProperties.Name=\"{Binding Name}\">\n                        <Grid.RowDefinitions>\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                        </Grid.RowDefinitions>\n                        <TextBlock Style=\"{StaticResource BodyStrongTextBlockStyle}\" Text=\"{Binding Name}\" />\n                        <StackPanel Grid.Row=\"1\" Orientation=\"Horizontal\">\n                            <TextBlock Text=\"{Binding Fit, Converter={StaticResource EnumValueConverter}, ConverterParameter=ThirdPersonSingular}\" />\n                            <TextBlock\n                                Margin=\"4,0,0,0\"\n                                Style=\"{StaticResource BodyStrongTextBlockStyle}\"\n                                Text=\"{Binding Width, Converter={StaticResource AutoDoubleConverter}, ConverterParameter=Auto}\" />\n                            <TextBlock\n                                Margin=\"4,0,0,0\"\n                                Foreground=\"{DynamicResource TextFillColorSecondaryBrush}\"\n                                Text=\"×\"\n                                Visibility=\"{Binding ShowHeight, Converter={StaticResource BoolValueConverter}}\" />\n                            <TextBlock\n                                Margin=\"4,0,0,0\"\n                                Style=\"{StaticResource BodyStrongTextBlockStyle}\"\n                                Text=\"{Binding Height, Converter={StaticResource AutoDoubleConverter}, ConverterParameter=Auto}\"\n                                Visibility=\"{Binding ShowHeight, Converter={StaticResource BoolValueConverter}}\" />\n                            <TextBlock Margin=\"4,0,0,0\" Text=\"{Binding Unit, Converter={StaticResource EnumValueConverter}, ConverterParameter=ToLower2}\" />\n                        </StackPanel>\n                    </Grid>\n                </DataTemplate>\n\n                <DataTemplate DataType=\"{x:Type m:CustomSize}\">\n                    <Grid VerticalAlignment=\"Center\" AutomationProperties.Name=\"{Binding Name}\">\n                        <TextBlock FontWeight=\"SemiBold\" Text=\"{Binding Name}\" />\n                    </Grid>\n                </DataTemplate>\n            </ComboBox.Resources>\n        </ComboBox>\n\n        <Grid Grid.Row=\"1\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"*\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n            </Grid.RowDefinitions>\n            <Border\n                Grid.RowSpan=\"5\"\n                Background=\"{DynamicResource LayerFillColorDefaultBrush}\"\n                BorderBrush=\"{DynamicResource CardStrokeColorDefaultBrush}\"\n                BorderThickness=\"0,1,0,0\" />\n\n            <!--  \"Custom\" input matrix  -->\n            <Grid Margin=\"16\" Visibility=\"{Binding ElementName=SizeComboBox, Path=SelectedValue, Converter={StaticResource SizeTypeToVisibilityConverter}}\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"24\" />\n                    <ColumnDefinition Width=\"*\" />\n                    <ColumnDefinition Width=\"24\" />\n                    <ColumnDefinition Width=\"24\" />\n                    <ColumnDefinition Width=\"*\" />\n                </Grid.ColumnDefinitions>\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"8\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n\n                <ui:SymbolIcon\n                    VerticalAlignment=\"Center\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Width}\"\n                    FontSize=\"20\"\n                    Foreground=\"{DynamicResource TextFillColorSecondaryBrush}\"\n                    Symbol=\"AutoFitWidth20\"\n                    ToolTipService.ToolTip=\"{x:Static p:Resources.Width}\" />\n                <ui:NumberBox\n                    Name=\"WidthNumberBox\"\n                    Grid.Column=\"1\"\n                    Margin=\"8,0,0,0\"\n                    HorizontalAlignment=\"Stretch\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Width}\"\n                    KeyDown=\"Button_KeyDown\"\n                    Minimum=\"0\"\n                    SpinButtonPlacementMode=\"Inline\">\n                    <ui:NumberBox.Value>\n                        <Binding\n                            ElementName=\"SizeComboBox\"\n                            Mode=\"TwoWay\"\n                            Path=\"SelectedValue.Width\"\n                            UpdateSourceTrigger=\"PropertyChanged\" />\n                    </ui:NumberBox.Value>\n                </ui:NumberBox>\n\n                <ui:SymbolIcon\n                    Grid.Column=\"3\"\n                    VerticalAlignment=\"Center\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Height}\"\n                    FontSize=\"20\"\n                    Foreground=\"{DynamicResource TextFillColorSecondaryBrush}\"\n                    Symbol=\"AutoFitHeight20\"\n                    ToolTipService.ToolTip=\"{x:Static p:Resources.Height}\"\n                    Visibility=\"{Binding ElementName=SizeComboBox, Path=SelectedValue.ShowHeight, Converter={StaticResource BoolValueConverter}}\" />\n                <ui:NumberBox\n                    Name=\"HeightNumberBox\"\n                    Grid.Column=\"4\"\n                    Margin=\"8,0,0,0\"\n                    HorizontalAlignment=\"Stretch\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Height}\"\n                    DataContext=\"{Binding ElementName=SizeComboBox, Path=SelectedItem}\"\n                    KeyDown=\"Button_KeyDown\"\n                    Minimum=\"0\"\n                    SpinButtonPlacementMode=\"Inline\"\n                    Visibility=\"{Binding ElementName=SizeComboBox, Path=SelectedValue.ShowHeight, Converter={StaticResource BoolValueConverter}}\">\n                    <ui:NumberBox.Value>\n                        <Binding\n                            ElementName=\"SizeComboBox\"\n                            Mode=\"TwoWay\"\n                            Path=\"SelectedValue.Height\"\n                            UpdateSourceTrigger=\"PropertyChanged\" />\n                    </ui:NumberBox.Value>\n                </ui:NumberBox>\n\n                <ui:SymbolIcon\n                    Grid.Row=\"2\"\n                    VerticalAlignment=\"Center\"\n                    FontSize=\"20\"\n                    Foreground=\"{DynamicResource TextFillColorSecondaryBrush}\"\n                    Symbol=\"Crop20\"\n                    ToolTipService.ToolTip=\"{x:Static p:Resources.Resize_Type}\" />\n                <ComboBox\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Margin=\"8,0,0,0\"\n                    HorizontalAlignment=\"Stretch\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Resize_Type}\"\n                    ItemsSource=\"{Binding ResizeFitValues, Mode=OneWay}\"\n                    SelectedIndex=\"{Binding ElementName=SizeComboBox, Path=SelectedValue.Fit, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}\">\n                    <ComboBox.ItemTemplate>\n                        <DataTemplate DataType=\"{x:Type m:ResizeFit}\">\n                            <TextBlock Padding=\"2,0\" Text=\"{Binding {}, Converter={StaticResource EnumValueConverter}}\" />\n                        </DataTemplate>\n                    </ComboBox.ItemTemplate>\n                </ComboBox>\n\n                <ui:SymbolIcon\n                    Grid.Row=\"2\"\n                    Grid.Column=\"3\"\n                    VerticalAlignment=\"Center\"\n                    FontSize=\"20\"\n                    Foreground=\"{DynamicResource TextFillColorSecondaryBrush}\"\n                    Symbol=\"Ruler20\"\n                    ToolTipService.ToolTip=\"{x:Static p:Resources.Unit}\" />\n                <ComboBox\n                    Grid.Row=\"2\"\n                    Grid.Column=\"4\"\n                    Margin=\"8,0,0,0\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Unit}\"\n                    ItemsSource=\"{Binding ResizeUnitValues, Mode=OneWay}\"\n                    SelectedIndex=\"{Binding ElementName=SizeComboBox, Path=SelectedValue.Unit, Mode=TwoWay, Converter={StaticResource EnumToIntConverter}}\">\n                    <ComboBox.ItemTemplate>\n                        <DataTemplate DataType=\"{x:Type m:ResizeUnit}\">\n                            <TextBlock Padding=\"2,0\" Text=\"{Binding {}, Converter={StaticResource EnumValueConverter}}\" />\n                        </DataTemplate>\n                    </ComboBox.ItemTemplate>\n                </ComboBox>\n            </Grid>\n\n            <!--  CheckBoxes  -->\n            <StackPanel\n                Grid.Row=\"1\"\n                Margin=\"16\"\n                Orientation=\"Vertical\">\n                <CheckBox AutomationProperties.Name=\"{Binding RelativeSource={RelativeSource Self}, Path=Content.(AccessText.Text), Converter={StaticResource AccessTextToTextConverter}}\" IsChecked=\"{Binding Settings.ShrinkOnly}\">\n                    <CheckBox.Content>\n                        <AccessText Text=\"{x:Static p:Resources.Input_ShrinkOnly}\" TextWrapping=\"Wrap\" />\n                    </CheckBox.Content>\n                </CheckBox>\n\n                <CheckBox AutomationProperties.Name=\"{Binding RelativeSource={RelativeSource Self}, Path=Content.(AccessText.Text), Converter={StaticResource AccessTextToTextConverter}}\" IsChecked=\"{Binding Settings.IgnoreOrientation}\">\n                    <CheckBox.Content>\n                        <AccessText Text=\"{x:Static p:Resources.Input_IgnoreOrientation}\" TextWrapping=\"Wrap\" />\n                    </CheckBox.Content>\n                </CheckBox>\n\n                <CheckBox AutomationProperties.Name=\"{Binding RelativeSource={RelativeSource Self}, Path=Content.(AccessText.Text), Converter={StaticResource AccessTextToTextConverter}}\" IsChecked=\"{Binding Settings.Replace}\">\n                    <CheckBox.Content>\n                        <AccessText Text=\"{x:Static p:Resources.Input_Replace}\" TextWrapping=\"Wrap\" />\n                    </CheckBox.Content>\n                </CheckBox>\n\n                <CheckBox AutomationProperties.Name=\"{Binding RelativeSource={RelativeSource Self}, Path=Content.(AccessText.Text), Converter={StaticResource AccessTextToTextConverter}}\" IsChecked=\"{Binding Settings.RemoveMetadata}\">\n                    <CheckBox.Content>\n                        <AccessText Text=\"{x:Static p:Resources.Input_RemoveMetadata}\" TextWrapping=\"Wrap\" />\n                    </CheckBox.Content>\n                </CheckBox>\n            </StackPanel>\n\n\n            <!--  Separator line  -->\n            <Border\n                Grid.Row=\"2\"\n                Height=\"1\"\n                Margin=\"0,8\"\n                HorizontalAlignment=\"Stretch\"\n                VerticalAlignment=\"Top\"\n                Background=\"{DynamicResource DividerStrokeColorDefaultBrush}\" />\n\n            <ui:InfoBar\n                Grid.Row=\"3\"\n                Margin=\"16,0\"\n                IsClosable=\"False\"\n                IsOpen=\"{Binding TryingToResizeGifFiles}\"\n                Message=\"{x:Static p:Resources.Input_GifWarning}\"\n                Severity=\"Warning\" />\n\n            <!--  Buttons  -->\n            <Grid Grid.Row=\"4\" Margin=\"16,8,16,16\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition />\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <ui:Button\n                    Padding=\"0\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Open_settings}\"\n                    Background=\"Transparent\"\n                    BorderBrush=\"Transparent\"\n                    Command=\"{Binding OpenSettingsCommand}\"\n                    ToolTipService.ToolTip=\"{x:Static p:Resources.Open_settings}\">\n                    <ui:Button.Content>\n                        <ui:SymbolIcon FontSize=\"20\" Symbol=\"Settings20\" />\n                    </ui:Button.Content>\n                </ui:Button>\n\n                <ui:Button\n                    Grid.Column=\"1\"\n                    MinWidth=\"76\"\n                    Appearance=\"Primary\"\n                    AutomationProperties.Name=\"{x:Static p:Resources.Resize_Tooltip}\"\n                    Command=\"{Binding ResizeCommand}\"\n                    IsDefault=\"True\">\n                    <StackPanel Orientation=\"Horizontal\">\n                        <ui:SymbolIcon FontSize=\"16\" Symbol=\"ResizeLarge16\" />\n                        <TextBlock Margin=\"8,0,0,0\" Text=\"{x:Static p:Resources.Input_Resize}\" />\n                    </StackPanel>\n                </ui:Button>\n\n                <ui:Button\n                    Grid.Column=\"2\"\n                    MinWidth=\"76\"\n                    Margin=\"8,0,0,0\"\n                    Command=\"{Binding CancelCommand}\"\n                    Content=\"{x:Static p:Resources.Cancel}\"\n                    IsCancel=\"True\" />\n            </Grid>\n        </Grid>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "PowerToys/src/modules/keyboardmanager/KeyboardManagerEditor/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Settings_Description\" xml:space=\"preserve\">\n    <value>本功能需要系统版本至少为 Win 10 1903</value>\n    <comment>Windows = the OS</comment>\n  </data>\n  <data name=\"KeyboardManager\" xml:space=\"preserve\">\n    <value>键盘修改器</value>\n  </data>\n  <data name=\"CreateWindowFailed_ErrorMessage\" xml:space=\"preserve\">\n    <value>调用 CreateWindow 创建窗口失败！</value>\n  </data>\n  <data name=\"CreateWindowFailed_ErrorTitle\" xml:space=\"preserve\">\n    <value>错误</value>\n  </data>\n  <data name=\"RegisterClassFailed_ErrorMessage\" xml:space=\"preserve\">\n    <value>Windows 重映射注册失败！</value>\n    <comment>This refers to an application window</comment>\n  </data>\n  <data name=\"RegisterClassFailed_ErrorTitle\" xml:space=\"preserve\">\n    <value>错误</value>\n  </data>\n  <data name=\"EditKeyboard_WindowName\" xml:space=\"preserve\">\n    <value>单键重映射</value>\n    <comment>keys on a keyboard</comment>\n  </data>\n  <data name=\"EditShortcuts_WindowName\" xml:space=\"preserve\">\n    <value>组合键重映射</value>\n  </data>\n  <data name=\"Edit_This_Shortcut_WindowName\" xml:space=\"preserve\">\n    <value>编辑按键</value>\n  </data>\n  <data name=\"Browse_For_Program_Button\" xml:space=\"preserve\">\n    <value>选择程序</value>\n  </data>\n  <data name=\"Browse_For_Path_Button\" xml:space=\"preserve\">\n    <value>选择目录</value>\n  </data>\n  <data name=\"Ok_Button\" xml:space=\"preserve\">\n    <value>确定</value>\n  </data>\n  <data name=\"Cancel_Button\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"Continue_Button\" xml:space=\"preserve\">\n    <value>确定</value>\n  </data>\n  <data name=\"EditKeyboard_SourceHeader\" xml:space=\"preserve\">\n    <value>按下</value>\n    <comment>verb, alternative to \"type a key on a keyboard\"</comment>\n  </data>\n  <data name=\"EditKeyboard_TargetHeader\" xml:space=\"preserve\">\n    <value>发送</value>\n  </data>\n  <data name=\"EditShortcuts_TargetHeader\" xml:space=\"preserve\">\n    <value>发送</value>\n  </data>\n  <data name=\"EditShortcuts_TargetAppHeader\" xml:space=\"preserve\">\n    <value>目标程序</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Args\" xml:space=\"preserve\">\n    <value>参数</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Elevation\" xml:space=\"preserve\">\n    <value>权限</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Start_As\" xml:space=\"preserve\">\n    <value>可见性</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Program\" xml:space=\"preserve\">\n    <value>程序</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Start_In\" xml:space=\"preserve\">\n    <value>起始目录</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Action\" xml:space=\"preserve\">\n    <value>操作</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Path_URI\" xml:space=\"preserve\">\n    <value>网址</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Shortcut\" xml:space=\"preserve\">\n    <value>按键</value>\n  </data>\n  <data name=\"EditShortcuts_Label_Keys\" xml:space=\"preserve\">\n    <value>文本</value>\n  </data>\n  <data name=\"EditShortcuts_Visibility_Normal\" xml:space=\"preserve\">\n    <value>正常</value>\n  </data>\n  <data name=\"EditShortcuts_Visibility_Hidden\" xml:space=\"preserve\">\n    <value>隐藏</value>\n  </data>\n  <data name=\"EditShortcuts_Label_If_Running\" xml:space=\"preserve\">\n    <value>若已运行</value>\n  </data>\n  <data name=\"EditShortcuts_Label_App_Running_Sound\" xml:space=\"preserve\">\n    <value>运行中音效</value>\n  </data>\n  <data name=\"EditShortcuts_LabelApp_Not_Running_Sound\" xml:space=\"preserve\">\n    <value>启动音效</value>\n  </data>\n  <data name=\"EditShortcuts_Bad_Key\" xml:space=\"preserve\">\n    <value>按键被占用</value>\n  </data>\n  <data name=\"EditShortcuts_BtnSelectFile\" xml:space=\"preserve\">\n    <value>选择文件</value>\n  </data>\n  <data name=\"EditKeyboard_OrphanedDialogTitle\" xml:space=\"preserve\">\n    <value>以下功能未分配：</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"EditKeyboard_PartialConfirmationDialogTitle\" xml:space=\"preserve\">\n    <value>部分按键映射失败</value>\n  </data>\n  <data name=\"EditShortcuts_PartialConfirmationDialogTitle\" xml:space=\"preserve\">\n    <value>部分组合键映射失败</value>\n  </data>\n  <data name=\"EditKeyboard_Info\" xml:space=\"preserve\">\n    <value>选择要修改的按键和按下后发送的功能</value>\n  </data>\n  <data name=\"EditKeyboard_InfoExample\" xml:space=\"preserve\">\n    <value>例如，若要按下 A 来复制，把 A 映射为发送 Ctrl+C 即可。若要按键互换，可以互相映射。</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"EditShortcuts_Info\" xml:space=\"preserve\">\n    <value>选择要修改的按键组合和按下后发送的功能</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"Edit_Single_Shortcut_Info\" xml:space=\"preserve\">\n    <value>选择要修改的按键组合和按下后发送的功能</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"EditShortcuts_InfoExample\" xml:space=\"preserve\">\n    <value>例如，若要在 Edge 浏览器中把 Alt+T 变成 Ctrl+T，请把 Alt+T 映射为发送 Ctrl+T，目标程序设为 MSEdge。\n目标程序是指 exe 文件名（MSEdge），而不是软件名（Microsoft Edge）。\n重映射单键优先于组合键生效。</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"Type_Button\" xml:space=\"preserve\">\n    <value>选择</value>\n    <comment>verb, alternative to \"type a key on a keyboard\"</comment>\n  </data>\n  <data name=\"TypeKey_Title\" xml:space=\"preserve\">\n    <value>请按下单个按键</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"TypeShortcut_Title\" xml:space=\"preserve\">\n    <value>请按下按键</value>\n    <comment>Keys on a keyboard</comment>\n  </data>\n  <data name=\"TypeKey_Header\" xml:space=\"preserve\">\n    <value>当前选择了：</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"TypeShortcut_Header\" xml:space=\"preserve\">\n    <value>当前选择了：</value>\n    <comment>Keys on a keyboard</comment>\n  </data>\n  <data name=\"Type_HoldSpace\" xml:space=\"preserve\">\n    <value>长按空格切换和弦（依次按下两个键触发）</value>\n  </data>\n  <data name=\"Type_HoldBackSpace\" xml:space=\"preserve\">\n    <value>长按退格切换严格匹配</value>\n  </data>\n  <data name=\"Type_HoldEnter\" xml:space=\"preserve\">\n    <value>长按回车确定</value>\n  </data>\n  <data name=\"Type_HoldEsc\" xml:space=\"preserve\">\n    <value>长按 Esc 取消</value>\n  </data>\n  <data name=\"EditShortcuts_AllApps\" xml:space=\"preserve\">\n    <value>（全局生效）</value>\n  </data>\n  <data name=\"EditShortcuts_Allow_Chords\" xml:space=\"preserve\">\n    <value>启用和弦序列</value>\n  </data>\n  <data name=\"EditShortcuts_Exact_Match\" xml:space=\"preserve\">\n    <value>严格匹配</value>\n  </data>\n  <data name=\"EditShortcuts_Path_To_Program\" xml:space=\"preserve\">\n    <value>程序文件路径</value>\n  </data>\n  <data name=\"EditShortcuts_Uri_Example\" xml:space=\"preserve\">\n    <value>例如 https://website.url</value>\n  </data>\n  <data name=\"EditShortcuts_What_Can_I_Use_Link\" xml:space=\"preserve\">\n    <value>更多高级操作</value>\n  </data>\n  <data name=\"EditShortcuts_Args_For_Program\" xml:space=\"preserve\">\n    <value>传入的参数</value>\n  </data>\n  <data name=\"EditShortcuts_Start_In_Dir_For_Program\" xml:space=\"preserve\">\n    <value>起始目录</value>\n  </data>\n  <data name=\"ErrorMessage_RemapSuccessful\" xml:space=\"preserve\">\n    <value>成功映射</value>\n  </data>\n  <data name=\"ErrorMessage_RemapUnsuccessful\" xml:space=\"preserve\">\n    <value>部分映射设置失败</value>\n  </data>\n  <data name=\"ErrorMessage_SameKeyPreviouslyMapped\" xml:space=\"preserve\">\n    <value>一个按键不能同时发送多个功能</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_MappedToSameKey\" xml:space=\"preserve\">\n    <value>您这啥也没改</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_ConflictingModifierKey\" xml:space=\"preserve\">\n    <value>与另一映射冲突</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_SameShortcutPreviouslyMapped\" xml:space=\"preserve\">\n    <value>一个按键组合不能同时发送多个功能</value>\n  </data>\n  <data name=\"ErrorMessage_MapToSameShortcut\" xml:space=\"preserve\">\n    <value>您这啥也没改</value>\n  </data>\n  <data name=\"ErrorMessage_ConflictingModifierShortcut\" xml:space=\"preserve\">\n    <value>与另一映射冲突</value>\n  </data>\n  <data name=\"ErrorMessage_WinL\" xml:space=\"preserve\">\n    <value>无法修改 Win+L</value>\n    <comment>Win refers to the key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_CtrlAltDel\" xml:space=\"preserve\">\n    <value>无法修改 Ctrl+Alt+Del</value>\n  </data>\n  <data name=\"ErrorMessage_SaveFailed\" xml:space=\"preserve\">\n    <value>映射保存失败</value>\n  </data>\n  <data name=\"ErrorMessage_ShortcutStartWithModifier\" xml:space=\"preserve\">\n    <value>必须以修饰键开头</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_ShortcutNoRepeatedModifier\" xml:space=\"preserve\">\n    <value>按键重复</value>\n  </data>\n  <data name=\"ErrorMessage_ShortcutAtleast2Keys\" xml:space=\"preserve\">\n    <value>至少应有两个键</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_ShortcutOneActionKey\" xml:space=\"preserve\">\n    <value>必须有操作键</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_ShortcutMaxOneActionKey\" xml:space=\"preserve\">\n    <value>最多只能有一个操作键</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_MaxShortcutSize\" xml:space=\"preserve\">\n    <value>最多只能有两个修饰键</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"ErrorMessage_Default\" xml:space=\"preserve\">\n    <value>未知错误</value>\n  </data>\n  <data name=\"Key_DropDown_Combobox\" xml:space=\"preserve\">\n    <value>按键下拉选择栏</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"Mapping_Type_DropDown_Text\" xml:space=\"preserve\">\n    <value>输入文本</value>\n    <comment>Text as in that the shortcut will be mapped into a sequence of characters. This is not about mobile text messages.</comment>\n  </data>\n  <data name=\"Mapping_Type_DropDown_Key_Shortcut\" xml:space=\"preserve\">\n    <value>发送按键</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"Mapping_Type_DropDown_Run_Program\" xml:space=\"preserve\">\n    <value>运行程序</value>\n    <comment>Run Program</comment>\n  </data>\n  <data name=\"Mapping_Type_DropDown_Open_URI\" xml:space=\"preserve\">\n    <value>打开网址</value>\n    <comment>URI to open.</comment>\n  </data>\n  <data name=\"Add_Key_Remap_Button\" xml:space=\"preserve\">\n    <value>添加单键重映射</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"Add_Shortcut_Button\" xml:space=\"preserve\">\n    <value>添加组合键重映射</value>\n  </data>\n  <data name=\"Delete_Remapping_Button\" xml:space=\"preserve\">\n    <value>删除映射</value>\n  </data>\n  <data name=\"Already_Running_Do_Nothing\" xml:space=\"preserve\">\n    <value>不执行任何操作</value>\n  </data>\n  <data name=\"Already_Running_Show_Window\" xml:space=\"preserve\">\n    <value>打开窗口</value>\n  </data>\n  <data name=\"Already_Running_Start_Another\" xml:space=\"preserve\">\n    <value>再次运行</value>\n  </data>\n  <data name=\"Already_Running_Close\" xml:space=\"preserve\">\n    <value>关闭程序</value>\n  </data>\n  <data name=\"Already_Running_Terminate\" xml:space=\"preserve\">\n    <value>强制结束进程</value>\n  </data>\n  <data name=\"Already_Running_Close_And_Terminate\" xml:space=\"preserve\">\n    <value>关闭并强制结束</value>\n  </data>\n  <data name=\"Elevation_Type_Normal\" xml:space=\"preserve\">\n    <value>正常</value>\n  </data>\n  <data name=\"Elevation_Type_Elevated\" xml:space=\"preserve\">\n    <value>管理员</value>\n  </data>\n  <data name=\"Elevation_Type_Different_User\" xml:space=\"preserve\">\n    <value>其他用户</value>\n  </data>\n  <data name=\"Delete_Remapping_Event\" xml:space=\"preserve\">\n    <value>映射已删除</value>\n  </data>\n  <data name=\"AutomationProperties_Row\" xml:space=\"preserve\">\n    <value>滚动行</value>\n    <comment>Row as in horizontal rows in a table, and columns</comment>\n  </data>\n  <data name=\"ERRORMESSAGE_DISABLEASACTIONKEY\" xml:space=\"preserve\">\n    <value>“禁用”不能作为按键</value>\n    <comment>Key on a keyboard</comment>\n  </data>\n  <data name=\"EditShortcuts_SourceHeader\" xml:space=\"preserve\">\n    <value>选择</value>\n    <comment>key sequence on a keyboard, example: Ctrl+C to copy a string</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/keyboardmanager/KeyboardManagerEngineLibrary/KeyboardEventHandlers.cpp",
    "content": "﻿#include \"pch.h\"\n#include <shellapi.h>\n#include \"KeyboardEventHandlers.h\"\n\n#include <common/interop/shared_constants.h>\n#include <common/utils/elevation.h>\n\n#include <keyboardmanager/common/InputInterface.h>\n#include <keyboardmanager/common/Helpers.h>\n#include <keyboardmanager/KeyboardManagerEngineLibrary/trace.h>\n\n#include <TlHelp32.h>\n#include <thread>\n#include <future>\n#include <chrono>\n\n#include <winrt/Windows.UI.Notifications.h>\n#include <winrt/Windows.Data.Xml.Dom.h>\n\n#include <windows.h>\n#include <string>\n#include <urlmon.h>\n#include <mmsystem.h>\n\nusing namespace winrt;\nusing namespace Windows::UI::Notifications;\nusing namespace Windows::Data::Xml::Dom;\n\nnamespace\n{\n    bool GeneratedByKBM(const LowlevelKeyboardEvent* data)\n    {\n        return data->lParam->dwExtraInfo & CommonSharedConstants::KEYBOARDMANAGER_INJECTED_FLAG;\n    }\n\n    void UpdateNumpadWithShift(LowlevelKeyboardEvent* data, State& state)\n    {\n        //Function for fixing numpad when used as shift https://github.com/microsoft/PowerToys/issues/22346\n        //VK_CLEAR is not encoded in IsNumpadOriginated\n        if (Helpers::IsNumpadOriginated(data->lParam->vkCode) || data->lParam->vkCode == VK_CLEAR)\n        {\n            // Decode it. If it is VK_CLEAR it will do nothing\n            DWORD decodedKey = Helpers::ClearKeyNumpadOrigin(data->lParam->vkCode);\n            //check if we already have a stored scanID\n            auto scanKey = MapVirtualKey(decodedKey, MAPVK_VK_TO_VSC);\n            auto it = state.scanMap.find(scanKey);\n            if (it != state.scanMap.end())\n            {\n                auto keyIt = state.GetSingleKeyRemap(it->second);\n                if (keyIt)\n                {\n                    //if key is stored as shift replace it with the numpad key\n                    auto keyValue = keyIt.value();\n                    if (keyValue->second.index() == 0)\n                    {\n                        auto key = std::get<DWORD>(keyValue->second);\n                        if (key == VK_LSHIFT || key == VK_RSHIFT || key == VK_SHIFT)\n                        {\n                            if (state.numpadKeyPressed[it->second])\n                            {\n                                //replace it with original numpad\n                                data->lParam->vkCode = it->second;\n                            }\n                        }\n                    }\n                    if (keyValue->second.index() == 1)\n                    {\n                        auto key = std::get<Shortcut>(keyValue->second);\n                        if (key.shiftKey != ModifierKey::Disabled)\n                        {\n                            if (state.numpadKeyPressed[it->second])\n                            { \n                                //replace it with original numpad\n                                data->lParam->vkCode = it->second;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        if (Helpers::IsNumpadKeyThatIsAffectedByShift(data->lParam->vkCode))\n        {\n            // store if the Numpad key was pressed or not. If numpad numbers were pressed but then we get the same key KEY UP but with Numpad unlocked we will replace it.\n            state.numpadKeyPressed[data->lParam->vkCode] = (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN);\n        }\n    }\n}\n\nnamespace KeyboardEventHandlers\n{\n    // Function to a handle a single key remap\n    intptr_t HandleSingleKeyRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept\n    {\n        // Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.\n        if (!GeneratedByKBM(data))\n        {\n            UpdateNumpadWithShift(data, state);\n            const auto remapping = state.GetSingleKeyRemap(data->lParam->vkCode);\n            if (remapping)\n            {\n                auto it = remapping.value();\n\n                // Check if the remap is to a key or a shortcut\n                const bool remapToKey = it->second.index() == 0;\n\n                // If mapped to VK_DISABLED then the key is disabled\n                if (remapToKey)\n                {\n                    if (std::get<DWORD>(it->second) == CommonSharedConstants::VK_DISABLED)\n                    {\n                        return 1;\n                    }\n                }\n\n                int key_count;\n                if (remapToKey)\n                {\n                    key_count = 1;\n                }\n                else\n                {\n                    key_count = std::get<Shortcut>(it->second).Size();\n                }\n\n                std::vector<INPUT> keyEventList;\n\n                // Handle remaps to VK_WIN_BOTH\n                DWORD target;\n                if (remapToKey)\n                {\n                    target = Helpers::FilterArtificialKeys(std::get<DWORD>(it->second));\n                }\n                else\n                {\n                    target = Helpers::FilterArtificialKeys(std::get<Shortcut>(it->second).GetActionKey());\n                }\n\n                // If Ctrl/Alt/Shift is being remapped to Caps Lock, then reset the modifier key state to fix issues in certain IME keyboards where the IME shortcut gets invoked since it detects that the modifier and Caps Lock is pressed even though it is suppressed by the hook - More information at the GitHub issue https://github.com/microsoft/PowerToys/issues/3397\n                if (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN)\n                {\n                    ResetIfModifierKeyForLowerLevelKeyHandlers(ii, it->first, target);\n                }\n\n                if (remapToKey)\n                {\n                    if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)\n                    {\n                        Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(target), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n                    }\n                    else\n                    {\n                        Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(target), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n                    }\n                }\n                else\n                {\n                    Shortcut targetShortcut = std::get<Shortcut>(it->second);\n                    if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)\n                    {\n                        Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(targetShortcut.GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n                        Helpers::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n                        // Dummy key is not required here since SetModifierKeyEvents will only add key-up events for the modifiers here, and the action key key-up is already sent before it\n                    }\n                    else\n                    {\n                        // Dummy key is not required here since SetModifierKeyEvents will only add key-down events for the modifiers here, and the action key key-down is already sent after it\n                        Helpers::SetModifierKeyEvents(targetShortcut, ModifierKey::Disabled, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n                        Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(targetShortcut.GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n                    }\n                }\n\n                ii.SendVirtualInput(keyEventList);\n\n                if (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN)\n                {\n                    // If Caps Lock is being remapped to Ctrl/Alt/Shift, then reset the modifier key state to fix issues in certain IME keyboards where the IME shortcut gets invoked since it detects that the modifier and Caps Lock is pressed even though it is suppressed by the hook - More information at the GitHub issue https://github.com/microsoft/PowerToys/issues/3397\n                    if (remapToKey)\n                    {\n                        ResetIfModifierKeyForLowerLevelKeyHandlers(ii, target, it->first);\n                    }\n                    else\n                    {\n                        std::vector<DWORD> shortcutKeys = std::get<Shortcut>(it->second).GetKeyCodes();\n                        for (auto& itSk : shortcutKeys)\n                        {\n                            ResetIfModifierKeyForLowerLevelKeyHandlers(ii, itSk, it->first);\n                        }\n                    }\n\n                    // Send daily telemetry event for Keyboard Manager key activation.\n                    if (remapToKey)\n                    {\n                        static int dayWeLastSentKeyToKeyTelemetryOn = -1;\n                        auto currentDay = std::chrono::duration_cast<std::chrono::days>(std::chrono::system_clock::now().time_since_epoch()).count();\n                        if (dayWeLastSentKeyToKeyTelemetryOn != currentDay)\n                        {\n                            Trace::DailyKeyToKeyRemapInvoked();\n                            dayWeLastSentKeyToKeyTelemetryOn = currentDay;\n                        }\n                    }\n                    else\n                    {\n                        static int dayWeLastSentKeyToShortcutTelemetryOn = -1;\n                        auto currentDay = std::chrono::duration_cast<std::chrono::days>(std::chrono::system_clock::now().time_since_epoch()).count();\n                        if (dayWeLastSentKeyToShortcutTelemetryOn != currentDay)\n                        {\n                            Trace::DailyKeyToShortcutRemapInvoked();\n                            dayWeLastSentKeyToShortcutTelemetryOn = currentDay;\n                        }\n                    }\n                }\n\n                return 1;\n            }\n        }\n\n        return 0;\n    }\n\n    /* This feature has not been enabled (code from proof of concept stage)\n    * \n    // Function to a change a key's behavior from toggle to modifier\n    __declspec(dllexport) intptr_t HandleSingleKeyToggleToModEvent(InputInterface& ii, LowlevelKeyboardEvent* data, State& State) noexcept\n    {\n        // Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.\n        if (!(data->lParam->dwExtraInfo & CommonSharedConstants::KEYBOARDMANAGER_INJECTED_FLAG))\n        {\n            // The mutex should be unlocked before SendInput is called to avoid re-entry into the same mutex. More details can be found at https://github.com/microsoft/PowerToys/pull/1789#issuecomment-607555837\n            std::unique_lock<std::mutex> lock(State.singleKeyToggleToMod_mutex);\n            auto it = State.singleKeyToggleToMod.find(data->lParam->vkCode);\n            if (it != State.singleKeyToggleToMod.end())\n            {\n                // To avoid long presses (which leads to continuous keydown messages) from toggling the key on and off\n                if (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN)\n                {\n                    if (it->second == false)\n                    {\n                        State.singleKeyToggleToMod[data->lParam->vkCode] = true;\n                    }\n                    else\n                    {\n                        lock.unlock();\n                        return 1;\n                    }\n                }\n                std::vector<INPUT> keyEventList;\n                Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, 0, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n                Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, (WORD)data->lParam->vkCode, KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SINGLEKEY_FLAG);\n\n                lock.unlock();\n                ii.SendVirtualInput(keyEventList);\n\n                // Reset the long press flag when the key has been lifted.\n                if (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP)\n                {\n                    lock.lock();\n                    State.singleKeyToggleToMod[data->lParam->vkCode] = false;\n                    lock.unlock();\n                }\n\n                return 1;\n            }\n        }\n\n        return 0;\n    }\n    */\n\n    // Function to a handle a shortcut remap\n    intptr_t HandleShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state, const std::optional<std::wstring>& activatedApp) noexcept\n    {\n        auto resetChordsResults = ResetChordsIfNeeded(data, state, activatedApp);\n\n        // Check if any shortcut is currently in the invoked state\n        bool isShortcutInvoked = state.CheckShortcutRemapInvoked(activatedApp);\n\n        // Get shortcut table for given activatedApp\n        ShortcutRemapTable& reMap = state.GetShortcutRemapTable(activatedApp);\n\n        // Iterate through the shortcut remaps and apply whichever has been pressed\n        for (auto& itShortcut : state.GetSortedShortcutRemapVector(activatedApp))\n        {\n            const auto it = reMap.find(itShortcut);\n\n            // If a shortcut is currently in the invoked state then skip till the shortcut that is currently invoked\n            if (isShortcutInvoked && !it->second.isShortcutInvoked)\n            {\n                continue;\n            }\n\n            // Check if the remap is to a key or a shortcut\n            const bool remapToKey = it->second.targetShortcut.index() == 0;\n            const bool remapToShortcut = it->second.targetShortcut.index() == 1;\n            const bool remapToText = it->second.targetShortcut.index() == 2;\n            const bool isRunProgram = (remapToShortcut && std::get<Shortcut>(it->second.targetShortcut).IsRunProgram());\n            const bool isOpenUri = (remapToShortcut && std::get<Shortcut>(it->second.targetShortcut).IsOpenURI());\n            const size_t src_size = it->first.Size();\n            const size_t dest_size = remapToShortcut ? std::get<Shortcut>(it->second.targetShortcut).Size() : 1;\n\n            bool isMatchOnChordEnd = false;\n            bool isMatchOnChordStart = false;\n\n            static bool isAltRightKeyInvoked = false;\n\n            // Check if the right Alt key (AltGr) is pressed.\n            if (data->lParam->vkCode == VK_RMENU && ii.GetVirtualKeyState(VK_LCONTROL))\n            {\n                isAltRightKeyInvoked = true;\n            }\n\n            // If the shortcut has been pressed down\n            if (!it->second.isShortcutInvoked && it->first.CheckModifiersKeyboardState(ii))\n            {\n                // if not a mod key, check for chord stuff\n                if (!resetChordsResults.CurrentKeyIsModifierKey && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))\n                {\n                    if (it->first.exactMatch == true && !it->first.IsKeyboardStateClearExceptShortcut(ii))\n                    {\n                        continue;\n                    }\n\n                    if (itShortcut.HasChord())\n                    {\n                        if (!resetChordsResults.AnyChordStarted && data->lParam->vkCode == itShortcut.GetActionKey() && !itShortcut.IsChordStarted() && itShortcut.HasChord())\n                        {\n                            // start new chord\n                            // Logger::trace(L\"ChordKeyboardHandler:new chord started for {}\", data->lParam->vkCode);\n                            isMatchOnChordStart = true;\n                            ResetAllOtherStartedChords(state, activatedApp, data->lParam->vkCode);\n                            itShortcut.SetChordStarted(true);\n                            continue;\n                        }\n\n                        if (itShortcut.IsChordStarted() && itShortcut.HasChord())\n                        {\n                            if (data->lParam->vkCode == itShortcut.GetSecondKey())\n                            {\n                                Logger::trace(L\"ChordKeyboardHandler:found chord match {}, {}\", itShortcut.GetActionKey(), itShortcut.GetSecondKey());\n                                isMatchOnChordEnd = true;\n                            }\n                            // Resets chord status for the shortcut. A key was pressed and we registered if it was the end of the chord. We can reset it.\n                            if (data->lParam->vkCode != itShortcut.GetActionKey())\n                            {\n                                itShortcut.SetChordStarted(false);\n                            }\n                        }\n\n                        if (resetChordsResults.AnyChordStarted && !isMatchOnChordEnd)\n                        {\n                            // Logger::trace(L\"ChordKeyboardHandler:waiting on second key of chord, checked {} for {}\", itShortcut.GetSecondKey(), data->lParam->vkCode);\n                            // this is a key and there is a mod, but it's not the second key of a chord.\n                            // we can't do anything with this key, we're waiting.\n                            continue;\n                        }\n                    }\n                }\n\n                if (isMatchOnChordEnd || (!resetChordsResults.AnyChordStarted && !itShortcut.HasChord() && (data->lParam->vkCode == it->first.GetActionKey() && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))))\n                {\n                    ResetAllStartedChords(state, activatedApp);\n                    resetChordsResults.AnyChordStarted = false;\n\n                    // Check if any other keys have been pressed apart from the shortcut. If true, then check for the next shortcut. This is to be done only for shortcut to shortcut remaps\n                    if (!it->first.IsKeyboardStateClearExceptShortcut(ii) && (remapToShortcut || (remapToKey && std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)))\n                    {\n                        continue;\n                    }\n\n                    std::vector<INPUT> keyEventList;\n\n                    // Remember which win key was pressed initially\n                    if (ii.GetVirtualKeyState(VK_RWIN))\n                    {\n                        it->second.winKeyInvoked = ModifierKey::Right;\n                    }\n                    else if (ii.GetVirtualKeyState(VK_LWIN))\n                    {\n                        it->second.winKeyInvoked = ModifierKey::Left;\n                    }\n\n                    if (isRunProgram)\n                    {\n                        auto threadFunction = [it]() {\n                            CreateOrShowProcessForShortcut(std::get<Shortcut>(it->second.targetShortcut));\n                        };\n\n                        std::thread myThread(threadFunction);\n                        if (myThread.joinable())\n                        {\n                            myThread.detach();\n                        }\n\n                        Logger::trace(L\"ChordKeyboardHandler:returning..\");\n                        return 1;\n                    }\n                    else if (isOpenUri)\n                    {\n                        auto shortcut = std::get<Shortcut>(it->second.targetShortcut);\n\n                        auto uri = shortcut.uriToOpen;\n                        auto newUri = uri;\n\n                        if (!PathIsURL(uri.c_str()))\n                        {\n                            WCHAR url[1024];\n                            DWORD bufferSize = 1024;\n\n                            if (UrlCreateFromPathW(uri.c_str(), url, &bufferSize, 0) == S_OK)\n                            {\n                                newUri = url;\n                                Logger::trace(L\"ChordKeyboardHandler:ConvertPathToURI from {} to {}\", uri, url);\n                            }\n                            else\n                            {\n                                // need access to text resources, maybe \"convert-resx-to-rc.ps1\" is not working to get\n                                // text from KeyboardManagerEditor to here in KeyboardManagerEngineLibrary land?\n                                toast(L\"错误\", L\"遇到了无法理解的路径或网址\");\n                                return 1;\n                            }\n                        }\n\n                        auto threadFunction = [newUri]() {\n                            HINSTANCE result = ShellExecute(NULL, L\"open\", newUri.c_str(), NULL, NULL, SW_SHOWNORMAL);\n\n                            if (result == reinterpret_cast<HINSTANCE>(HINSTANCE_ERROR))\n                            {\n                                // need access to text resources, maybe \"convert-resx-to-rc.ps1\" is not working to get\n                                // text from KeyboardManagerEditor to here in KeyboardManagerEngineLibrary land?\n                                toast(L\"错误\", L\"遇到了无法理解的路径或网址\");\n                            }\n                        };\n\n                        std::thread myThread(threadFunction);\n                        if (myThread.joinable())\n                        {\n                            myThread.detach();\n                        }\n\n                        Logger::trace(L\"ChordKeyboardHandler:returning..\");\n                        return 1;\n                    }\n                    else if (remapToShortcut)\n                    {\n                        // Get the common keys between the two shortcuts if this is not a runProgram shortcut\n\n                        int commonKeys = it->first.GetCommonModifiersCount(std::get<Shortcut>(it->second.targetShortcut));\n\n                        // If the original shortcut modifiers are a subset of the new shortcut\n                        if (commonKeys == src_size - 1)\n                        {\n                            // key down for all new shortcut keys except the common modifiers\n                            keyEventList = std::vector<INPUT>{};\n                            Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n                        else\n                        {\n                            // Dummy key, key up for all the original shortcut modifier keys and key down for all the new shortcut keys but common keys in each are not repeated\n                            // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->Ctrl+V, press Win+A, since Win will be released here we need to send a dummy event before it\n                            Helpers::SetDummyKeyEvent(keyEventList, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                            // Release original shortcut state (release in reverse order of shortcut to be accurate)\n                            Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));\n\n                            // Set new shortcut key down state\n                            Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n\n                        // Modifier state reset might be required for this key depending on the shortcut's action and target modifiers - ex: Win+Caps -> Ctrl+A\n                        if (it->first.GetCtrlKey() == NULL && it->first.GetAltKey() == NULL && it->first.GetShiftKey() == NULL)\n                        {\n                            Shortcut temp = std::get<Shortcut>(it->second.targetShortcut);\n                            for (auto keys : temp.GetKeyCodes())\n                            {\n                                ResetIfModifierKeyForLowerLevelKeyHandlers(ii, keys, data->lParam->vkCode);\n                            }\n                        }\n                    }\n                    else if (remapToKey)\n                    {\n                        // Do not send Disable key\n                        if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)\n                        {\n                            // Since the original shortcut's action key is pressed, set it to true\n                            it->second.isOriginalActionKeyPressed = true;\n                        }\n\n                        // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->V, press Win+A, since Win will be released here we need to send a dummy event before it\n                        Helpers::SetDummyKeyEvent(keyEventList, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                        // Release original shortcut state (release in reverse order of shortcut to be accurate)\n                        Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                        // Set target key down state\n                        if (std::get<DWORD>(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED)\n                        {\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n\n                        // Modifier state reset might be required for this key depending on the shortcut's action and target modifier - ex: Win+Caps -> Ctrl\n                        if (it->first.GetCtrlKey() == NULL && it->first.GetAltKey() == NULL && it->first.GetShiftKey() == NULL)\n                        {\n                            ResetIfModifierKeyForLowerLevelKeyHandlers(ii, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), data->lParam->vkCode);\n                        }\n                    }\n                    // Remapped to text\n                    else\n                    {\n                        auto& remapping = std::get<std::wstring>(it->second.targetShortcut);\n\n                        Helpers::SetDummyKeyEvent(keyEventList, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                        // Release original shortcut state (release in reverse order of shortcut to be accurate)\n                        Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                        Helpers::SetTextKeyEvents(keyEventList, remapping);\n                    }\n\n                    it->second.isShortcutInvoked = true;\n                    // If app specific shortcut is invoked, store the target application\n                    if (activatedApp)\n                    {\n                        state.SetActivatedApp(*activatedApp);\n                    }\n\n                    Logger::trace(L\"ChordKeyboardHandler:keyEventList.size:{}\", keyEventList.size());\n\n                    ii.SendVirtualInput(keyEventList);\n                    if (activatedApp.has_value())\n                    {\n                        if (remapToKey)\n                        {\n                            static int dayWeLastSentAppSpecificShortcutToKeyTelemetryOn = -1;\n                            auto currentDay = std::chrono::duration_cast<std::chrono::days>(std::chrono::system_clock::now().time_since_epoch()).count();\n                            if (dayWeLastSentAppSpecificShortcutToKeyTelemetryOn != currentDay)\n                            {\n                                Trace::DailyAppSpecificShortcutToKeyRemapInvoked();\n                                dayWeLastSentAppSpecificShortcutToKeyTelemetryOn = currentDay;\n                            }\n                        }\n                        else if (remapToShortcut && (!isRunProgram) && (!isOpenUri))\n                        {\n                            static int dayWeLastSentAppSpecificShortcutToShortcutTelemetryOn = -1;\n                            auto currentDay = std::chrono::duration_cast<std::chrono::days>(std::chrono::system_clock::now().time_since_epoch()).count();\n                            if (dayWeLastSentAppSpecificShortcutToShortcutTelemetryOn != currentDay)\n                            {\n                                Trace::DailyAppSpecificShortcutToShortcutRemapInvoked();\n                                dayWeLastSentAppSpecificShortcutToShortcutTelemetryOn = currentDay;\n                            }\n                        }\n                    }\n                    else\n                    {\n                        if (remapToKey)\n                        {\n                            static int dayWeLastSentShortcutToKeyTelemetryOn = -1;\n                            auto currentDay = std::chrono::duration_cast<std::chrono::days>(std::chrono::system_clock::now().time_since_epoch()).count();\n                            if (dayWeLastSentShortcutToKeyTelemetryOn != currentDay)\n                            {\n                                Trace::DailyShortcutToKeyRemapInvoked();\n                                dayWeLastSentShortcutToKeyTelemetryOn = currentDay;\n                            }\n                        }\n                        else if (remapToShortcut && (!isRunProgram) && (!isOpenUri))\n                        {\n                            static int dayWeLastSentShortcutToShortcutTelemetryOn = -1;\n                            auto currentDay = std::chrono::duration_cast<std::chrono::days>(std::chrono::system_clock::now().time_since_epoch()).count();\n                            if (dayWeLastSentShortcutToShortcutTelemetryOn != currentDay)\n                            {\n                                Trace::DailyShortcutToShortcutRemapInvoked();\n                                dayWeLastSentShortcutToShortcutTelemetryOn = currentDay;\n                            }\n                        }\n                    }\n\n                    return 1;\n                }\n            }\n            else if (it->second.isShortcutInvoked)\n            {\n                // The shortcut has already been pressed down at least once, i.e. the shortcut has been invoked\n                // There are 6 cases to be handled if the shortcut has been pressed down\n                // 1. The user lets go of one of the modifier keys - reset the keyboard back to the state of the keys actually being pressed down\n                // 2. The user keeps the shortcut pressed - the shortcut is repeated (for example you could hold down Ctrl+V and it will keep pasting)\n                // 3. The user lets go of the action key - keep modifiers of the new shortcut until some other key event which doesn't apply to the original shortcut\n                // 4. The user presses a modifier key in the original shortcut - suppress that key event since the original shortcut is already held down physically (This case can occur only if a user has a duplicated modifier key (possibly by remapping) or if user presses both L/R versions of a modifier remapped with \"Both\")\n                // 5. The user presses any key apart from the action key or a modifier key in the original shortcut - revert the keyboard state to just the original modifiers being held down along with the current key press\n                // 6. The user releases any key apart from original modifier or original action key - This can't happen since the key down would have to happen first, which is handled above\n\n                // Prevents the unintended release of the Ctrl part when AltGr is pressed. AltGr acts as both Ctrl and Alt being pressed.\n                // After triggering a shortcut involving AltGr, the system might attempt to release the Ctrl part. This code ensures Ctrl remains pressed, maintaining the AltGr state correctly.\n                if (isAltRightKeyInvoked && data->lParam->vkCode == VK_LCONTROL && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP))\n                {\n                    break;\n                }\n\n                // Get the common keys between the two shortcuts\n                int commonKeys = (remapToShortcut && !isRunProgram) ? it->first.GetCommonModifiersCount(std::get<Shortcut>(it->second.targetShortcut)) : 0;\n\n                // Case 1: If any of the modifier keys of the original shortcut are released before the action key\n                if ((it->first.CheckWinKey(data->lParam->vkCode) || it->first.CheckCtrlKey(data->lParam->vkCode) || it->first.CheckAltKey(data->lParam->vkCode) || it->first.CheckShiftKey(data->lParam->vkCode)) && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP))\n                {\n                    // Release new shortcut, and set original shortcut keys except the one released\n                    std::vector<INPUT> keyEventList;\n                    if (remapToShortcut && !isRunProgram)\n                    {\n                        // If the target shortcut's action key is pressed, then it should be released\n                        bool isActionKeyPressed = ii.GetVirtualKeyState(std::get<Shortcut>(it->second.targetShortcut).GetActionKey());\n\n                        // Release new shortcut state (release in reverse order of shortcut to be accurate)\n                        if (isActionKeyPressed)\n                        {\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n\n                        Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first, data->lParam->vkCode);\n\n                        if (!isAltRightKeyInvoked)\n                        {\n                            // Set original shortcut key down state except the action key and the released modifier since the original action key may or may not be held down. If it is held down it will generate its own key message\n                            Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut), data->lParam->vkCode);\n                        }\n                        else\n                        {\n                            isAltRightKeyInvoked = false;\n                        }\n\n                        // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+Ctrl+A->Ctrl+V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it\n                        Helpers::SetDummyKeyEvent(keyEventList, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                    }\n                    else if (remapToKey)\n                    {\n                        bool isTargetKeyPressed = (std::get<DWORD>(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED) && ii.GetVirtualKeyState(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)));\n\n                        // Release new key state\n                        if (std::get<DWORD>(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED && isTargetKeyPressed)\n                        {\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n\n                        // Ensures that after releasing both the action key and AltGr, Ctrl does not remain falsely pressed.\n                        if (!isAltRightKeyInvoked)\n                        {\n                            // Set original shortcut key down state except the action key and the released modifier since the original action key may or may not be held down. If it is held down it will generate its own key message\n                            Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, Shortcut(), data->lParam->vkCode);\n                        }\n                        else\n                        {\n                            isAltRightKeyInvoked = false;\n                        }\n\n                        // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+Ctrl+A->V, press Win+Ctrl+A and release A then Ctrl, since Win will be pressed here we need to send a dummy event after it\n                        Helpers::SetDummyKeyEvent(keyEventList, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                    }\n\n                    // Reset the remap state\n                    it->second.isShortcutInvoked = false;\n                    it->second.winKeyInvoked = ModifierKey::Disabled;\n                    it->second.isOriginalActionKeyPressed = false;\n\n                    // If app specific shortcut has finished invoking, reset the target application\n                    if (activatedApp)\n                    {\n                        state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);\n                    }\n\n                    ii.SendVirtualInput(keyEventList);\n                    return 1;\n                }\n\n                // The system will see the modifiers of the new shortcut as being held down because of the shortcut remap\n                if (!remapToShortcut || (remapToShortcut && std::get<Shortcut>(it->second.targetShortcut).CheckModifiersKeyboardState(ii)))\n                {\n                    // Case 2: If the original shortcut is still held down the keyboard will get a key down message of the action key in the original shortcut and the new shortcut's modifiers will be held down (keys held down send repeated keydown messages)\n                    if (((data->lParam->vkCode == it->first.GetActionKey() && !it->first.HasChord()) || (data->lParam->vkCode == it->first.GetSecondKey() && it->first.HasChord())) && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))\n                    {\n                        // In case of mapping to disable do not send anything\n                        if (remapToKey && std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)\n                        {\n                            // Since the original shortcut's action key is pressed, set it to true\n                            it->second.isOriginalActionKeyPressed = true;\n                            return 1;\n                        }\n\n                        std::vector<INPUT> keyEventList;\n                        if (remapToShortcut)\n                        {\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n                        else if (remapToKey)\n                        {\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n                        else if (remapToText)\n                        {\n                            auto& remapping = std::get<std::wstring>(it->second.targetShortcut);\n                            Helpers::SetTextKeyEvents(keyEventList, remapping);\n                        }\n\n                        ii.SendVirtualInput(keyEventList);\n                        return 1;\n                    }\n\n                    // Case 3: If the action key is released from the original shortcut, keep modifiers of the new shortcut until some other key event which doesn't apply to the original shortcut\n                    if (!remapToText && ((!it->first.HasChord() && data->lParam->vkCode == it->first.GetActionKey()) || (it->first.HasChord() && data->lParam->vkCode == it->first.GetSecondKey())) && (data->wParam == WM_KEYUP || data->wParam == WM_SYSKEYUP))\n                    {\n                        std::vector<INPUT> keyEventList;\n                        if (remapToShortcut && !it->first.HasChord())\n                        {\n                            // Just lift the action key for no chords.\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                        }\n                        else if (remapToShortcut && it->first.HasChord())\n                        {\n                            // If it has a chord, we'll want a full clean contemplated in the else, since you can't really repeat chords by pressing the end key again.\n\n                            // Key up for all new shortcut keys, key down for original shortcut modifiers and current key press but common keys aren't repeated\n                            Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                            // Release new shortcut state (release in reverse order of shortcut to be accurate)\n                            Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);\n\n                            // Set old shortcut key down state\n                            Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));\n\n                            // Reset the remap state\n                            it->second.isShortcutInvoked = false;\n                            it->second.winKeyInvoked = ModifierKey::Disabled;\n                            it->second.isOriginalActionKeyPressed = false;\n\n                            // If app specific shortcut has finished invoking, reset the target application\n                            if (activatedApp)\n                            {\n                                state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);\n                            }\n                        }\n                        else if (std::get<DWORD>(it->second.targetShortcut) == CommonSharedConstants::VK_DISABLED)\n                        {\n                            // If remapped to disable, do nothing and suppress the key event\n                            // Since the original shortcut's action key is released, set it to false\n                            it->second.isOriginalActionKeyPressed = false;\n                            return 1;\n                        }\n                        else\n                        {\n                            // Check if the keyboard state is clear apart from the target remap key (by creating a temp Shortcut object with the target key)\n                            bool isKeyboardStateClear = Shortcut(std::vector<int32_t>({ Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)) })).IsKeyboardStateClearExceptShortcut(ii);\n\n                            // If the keyboard state is clear, we release the target key but do not reset the remap state\n                            if (isKeyboardStateClear)\n                            {\n                                Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                            }\n                            else\n                            {\n                                // If any other key is pressed, then the keyboard state must be reverted back to the physical keys.\n                                // This is to take cases like Ctrl+A->D remap and user presses B+Ctrl+A and releases A, or Ctrl+A+B and releases A\n\n                                // Release new key state\n                                Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut))), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                                if (!isAltRightKeyInvoked)\n                                {\n                                    // Set original shortcut key down state except the action key\n                                    Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                }\n\n                                // Send a dummy key event to prevent modifier press+release from being triggered. Example: Win+A->V, press Shift+Win+A and release A, since Win will be pressed here we need to send a dummy event after it\n                                Helpers::SetDummyKeyEvent(keyEventList, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n\n                                if (!isAltRightKeyInvoked)\n                                {\n                                    // Reset the remap state\n                                    it->second.isShortcutInvoked = false;\n                                    it->second.winKeyInvoked = ModifierKey::Disabled;\n                                    it->second.isOriginalActionKeyPressed = false;\n                                }\n\n                                // If app specific shortcut has finished invoking, reset the target application\n                                if (activatedApp != KeyboardManagerConstants::NoActivatedApp)\n                                {\n                                    state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);\n                                }\n                            }\n                        }\n\n                        ii.SendVirtualInput(keyEventList);\n                        return 1;\n                    }\n\n                    // Case 4: If a modifier key in the original shortcut is pressed then suppress that key event since the original shortcut is already held down physically - This case can occur only if a user has a duplicated modifier key (possibly by remapping) or if user presses both L/R versions of a modifier remapped with \"Both\"\n                    if ((it->first.CheckWinKey(data->lParam->vkCode) || it->first.CheckCtrlKey(data->lParam->vkCode) || it->first.CheckAltKey(data->lParam->vkCode) || it->first.CheckShiftKey(data->lParam->vkCode)) && (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN))\n                    {\n                        if (remapToShortcut)\n                        {\n                            // Modifier state reset might be required for this key depending on the target shortcut action key - ex: Ctrl+A -> Win+Caps\n                            if (std::get<Shortcut>(it->second.targetShortcut).GetCtrlKey() == NULL && std::get<Shortcut>(it->second.targetShortcut).GetAltKey() == NULL && std::get<Shortcut>(it->second.targetShortcut).GetShiftKey() == NULL)\n                            {\n                                ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, std::get<Shortcut>(it->second.targetShortcut).GetActionKey());\n                            }\n                        }\n                        else if (std::get<DWORD>(it->second.targetShortcut) != CommonSharedConstants::VK_DISABLED)\n                        {\n                            // If it is not remapped to Disable\n                            // Modifier state reset might be required for this key depending on the target key - ex: Ctrl+A -> Caps\n                            ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, Helpers::FilterArtificialKeys(std::get<DWORD>(it->second.targetShortcut)));\n                        }\n\n                        // Suppress the modifier as it is already physically pressed\n                        return 1;\n                    }\n\n                    // Case 5: If any key apart from the action key or a modifier key in the original shortcut is pressed then revert the keyboard state to just the original modifiers being held down along with the current key press\n                    if (data->wParam == WM_KEYDOWN || data->wParam == WM_SYSKEYDOWN)\n                    {\n                        if (remapToShortcut)\n                        {\n                            // Modifier state reset might be required for this key depending on the target shortcut action key - ex: Ctrl+A -> Win+Caps, Shift is pressed. System should not see Shift and Caps pressed together\n                            if (std::get<Shortcut>(it->second.targetShortcut).GetCtrlKey() == NULL && std::get<Shortcut>(it->second.targetShortcut).GetAltKey() == NULL && std::get<Shortcut>(it->second.targetShortcut).GetShiftKey() == NULL)\n                            {\n                                ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, std::get<Shortcut>(it->second.targetShortcut).GetActionKey());\n                            }\n\n                            std::vector<INPUT> keyEventList;\n\n                            // Check if a new remapping should be applied\n                            Shortcut currentlyPressed = it->first;\n                            currentlyPressed.actionKey = data->lParam->vkCode;\n                            auto newRemappingIter = reMap.find(currentlyPressed);\n                            if (newRemappingIter != reMap.end() && !newRemappingIter->first.HasChord())\n                            {\n                                auto& newRemapping = newRemappingIter->second;\n                                Shortcut from = std::get<Shortcut>(it->second.targetShortcut);\n                                if (newRemapping.RemapToKey())\n                                {\n                                    DWORD to = std::get<0>(newRemapping.targetShortcut);\n                                    if (!isAltRightKeyInvoked)\n                                    {\n                                        Helpers::SetModifierKeyEvents(from, it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                    }\n                                    if (ii.GetVirtualKeyState(static_cast<WORD>(from.actionKey)))\n                                    {\n                                        // If the action key from the last shortcut is still being pressed, release it.\n                                        Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(from.actionKey), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                    }\n                                    Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(to), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                }\n                                else\n                                {\n                                    Shortcut to = std::get<Shortcut>(newRemapping.targetShortcut);\n                                    if (!isAltRightKeyInvoked)\n                                    {\n                                        Helpers::SetModifierKeyEvents(from, it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, to);\n                                    }\n                                    if (ii.GetVirtualKeyState(static_cast<WORD>(from.actionKey)))\n                                    {\n                                        // If the action key from the last shortcut is still being pressed, release it.\n                                        Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(from.actionKey), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                    }\n                                    if (!isAltRightKeyInvoked)\n                                    {\n                                        Helpers::SetModifierKeyEvents(to, it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, from);\n                                    }\n                                    Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(to.actionKey), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                    newRemapping.isShortcutInvoked = true;\n                                }\n\n                                // Remember which win key was pressed initially\n                                if (ii.GetVirtualKeyState(VK_RWIN))\n                                {\n                                    newRemapping.winKeyInvoked = ModifierKey::Right;\n                                }\n                                else if (ii.GetVirtualKeyState(VK_LWIN))\n                                {\n                                    newRemapping.winKeyInvoked = ModifierKey::Left;\n                                }\n                            }\n                            else\n                            {\n                                // If the target shortcut's action key is pressed, then it should be released and original shortcut's action key should be set\n                                bool isActionKeyPressed = ii.GetVirtualKeyState(std::get<Shortcut>(it->second.targetShortcut).GetActionKey());\n\n                                // Release new shortcut state (release in reverse order of shortcut to be accurate)\n                                if (isActionKeyPressed)\n                                {\n                                    Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(std::get<Shortcut>(it->second.targetShortcut).GetActionKey()), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                }\n                                if (!isAltRightKeyInvoked)\n                                {\n                                    Helpers::SetModifierKeyEvents(std::get<Shortcut>(it->second.targetShortcut), it->second.winKeyInvoked, keyEventList, false, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, it->first);\n\n                                    // Set old shortcut key down state\n                                    Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG, std::get<Shortcut>(it->second.targetShortcut));\n                                }\n\n                                // key down for original shortcut action key with shortcut flag so that we don't invoke the same shortcut remap again\n                                if (isActionKeyPressed)\n                                {\n                                    Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(it->first.GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                }\n\n                                // Send current key pressed without shortcut flag so that it can be reprocessed in case the physical keys pressed are a different remapped shortcut\n                                Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(data->lParam->vkCode), 0, 0);\n\n                                // Do not send a dummy key as we want the current key press to behave as normal i.e. it can do press+release functionality if required. Required to allow a shortcut to Win key remap invoked directly after shortcut to shortcut is released to open start menu\n                            }\n\n                            if (!isAltRightKeyInvoked)\n                            {\n                                // Reset the remap state\n                                it->second.isShortcutInvoked = false;\n                                it->second.winKeyInvoked = ModifierKey::Disabled;\n                                it->second.isOriginalActionKeyPressed = false;\n                            }\n\n                            // If app specific shortcut has finished invoking, reset the target application\n                            if (activatedApp)\n                            {\n                                state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);\n                            }\n\n                            ii.SendVirtualInput(keyEventList);\n                            return 1;\n                        }\n                        else\n                        {\n                            // For remap to key, if the original action key is not currently pressed, we should revert the keyboard state to the physical keys. If it is pressed we should not suppress the event so that shortcut to key remaps can be pressed with other keys. Example use-case: Alt+D->Win, allows Alt+D+A to perform Win+A\n\n                            // Modifier state reset might be required for this key depending on the target key - ex: Ctrl+A -> Caps, Shift is pressed. System should not see Shift and Caps pressed together\n\n                            auto maybeTargetKey = std::get_if<DWORD>(&it->second.targetShortcut);\n\n                            if (maybeTargetKey)\n                            {\n                                ResetIfModifierKeyForLowerLevelKeyHandlers(ii, data->lParam->vkCode, Helpers::FilterArtificialKeys(*maybeTargetKey));\n                            }\n\n                            // If the shortcut is remapped to Disable then we have to revert the keyboard state to the physical keys\n                            bool isRemapToDisable = maybeTargetKey && (*maybeTargetKey == CommonSharedConstants::VK_DISABLED);\n                            bool isOriginalActionKeyPressed = false;\n\n                            if (maybeTargetKey && !isRemapToDisable)\n                            {\n                                // If the remap target key is currently pressed, then we do not have to revert the keyboard state to the physical keys\n                                if (ii.GetVirtualKeyState((Helpers::FilterArtificialKeys(*maybeTargetKey))))\n                                {\n                                    isOriginalActionKeyPressed = true;\n                                }\n                            }\n                            else\n                            {\n                                isOriginalActionKeyPressed = it->second.isOriginalActionKeyPressed;\n                            }\n\n                            if (isRemapToDisable || !isOriginalActionKeyPressed)\n                            {\n                                std::vector<INPUT> keyEventList;\n\n                                if (!isAltRightKeyInvoked)\n                                {\n                                    // Set original shortcut key down state\n                                    Helpers::SetModifierKeyEvents(it->first, it->second.winKeyInvoked, keyEventList, true, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                }\n\n                                // Send the original action key only if it is physically pressed. For remappings to keys other than disabled we already check earlier that it is not pressed in this scenario. For remap to disable\n                                if (isRemapToDisable && isOriginalActionKeyPressed)\n                                {\n                                    // Set original action key\n                                    Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(it->first.GetActionKey()), 0, KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG);\n                                }\n\n                                // Send current key pressed without shortcut flag so that it can be reprocessed in case the physical keys pressed are a different remapped shortcut\n                                Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(data->lParam->vkCode), 0, 0);\n\n                                // Do not send a dummy key as we want the current key press to behave as normal i.e. it can do press+release functionality if required. Required to allow a shortcut to Win key remap invoked directly after another shortcut to key remap is released to open start menu\n\n                                if (!isAltRightKeyInvoked)\n                                {\n                                    // Reset the remap state\n                                    it->second.isShortcutInvoked = false;\n                                    it->second.winKeyInvoked = ModifierKey::Disabled;\n                                    it->second.isOriginalActionKeyPressed = false;\n                                }\n\n                                // If app specific shortcut has finished invoking, reset the target application\n                                if (activatedApp != KeyboardManagerConstants::NoActivatedApp)\n                                {\n                                    state.SetActivatedApp(KeyboardManagerConstants::NoActivatedApp);\n                                }\n\n                                ii.SendVirtualInput(keyEventList);\n                                return 1;\n                            }\n                            else\n                            {\n                                return 0;\n                            }\n                        }\n                    }\n                    // Case 6: If any key apart from original modifier or original action key is released - This can't happen since the key down would have to happen first, which is handled above. If a key up message is generated for some other key (maybe by code) do not suppress it\n                }\n            }\n        }\n\n        return 0;\n    }\n\n    std::wstring URL_encode(const std::wstring& filepath)\n    {\n        std::wostringstream escaped;\n        escaped.fill('0');\n        escaped << std::hex;\n\n        for (wchar_t ch : filepath)\n        {\n            // Encode special characters except for colon after drive letter\n            if (!iswalnum(ch) && ch != L'-' && ch != L'_' && ch != L'.' && ch != L'~' && !(ch == L':' && std::isalpha(filepath[0])))\n            {\n                escaped << std::uppercase;\n                //escaped << '%' << std::setw(2) << int((unsigned char)ch);\n                escaped << '%' << std::setw(2) << static_cast<int>((static_cast<unsigned char>(ch)));\n                escaped << std::nouppercase;\n            }\n            else\n            {\n                escaped << ch;\n            }\n        }\n\n        return escaped.str();\n    }\n\n    std::wstring ConvertPathToURI(const std::wstring& filePath)\n    {\n        std::wstring fileUri = std::filesystem::absolute(filePath).wstring();\n        std::replace(fileUri.begin(), fileUri.end(), L'\\\\', L'/');\n        fileUri = L\"file:///\" + URL_encode(fileUri);\n\n        return fileUri;\n    }\n\n    void ResetAllOtherStartedChords(State& state, const std::optional<std::wstring>& activatedApp, DWORD keyToKeep)\n    {\n        for (auto& itShortcut_2 : state.GetSortedShortcutRemapVector(activatedApp))\n        {\n            if (keyToKeep == NULL || itShortcut_2.actionKey != keyToKeep)\n            {\n                itShortcut_2.SetChordStarted(false);\n            }\n        }\n    }\n\n    void ResetAllStartedChords(State& state, const std::optional<std::wstring>& activatedApp)\n    {\n        ResetAllOtherStartedChords(state, activatedApp, NULL);\n    }\n\n    ResetChordsResults ResetChordsIfNeeded(LowlevelKeyboardEvent* data, State& state, const std::optional<std::wstring>& activatedApp)\n    {\n        ResetChordsResults result;\n        result.AnyChordStarted = false;\n        result.CurrentKeyIsModifierKey = false;\n\n        bool isNewControlKey = false;\n        bool anyChordStarted = false;\n        if (VK_LWIN == data->lParam->vkCode || VK_RWIN == data->lParam->vkCode)\n        {\n            isNewControlKey = true;\n        }\n        if (VK_LSHIFT == data->lParam->vkCode || VK_RSHIFT == data->lParam->vkCode)\n        {\n            isNewControlKey = true;\n        }\n        if (VK_LMENU == data->lParam->vkCode || VK_RMENU == data->lParam->vkCode)\n        {\n            isNewControlKey = true;\n        }\n        if (VK_LCONTROL == data->lParam->vkCode || VK_RCONTROL == data->lParam->vkCode)\n        {\n            isNewControlKey = true;\n        }\n\n        if (isNewControlKey)\n        {\n            //Logger::trace(L\"ChordKeyboardHandler:reset\");\n\n            for (auto& itShortcut : state.GetSortedShortcutRemapVector(activatedApp))\n            {\n                itShortcut.SetChordStarted(false);\n            }\n            result.CurrentKeyIsModifierKey = true;\n        }\n        else\n        {\n            for (auto& itShortcut : state.GetSortedShortcutRemapVector(activatedApp))\n            {\n                if (itShortcut.IsChordStarted())\n                {\n                    result.AnyChordStarted = true;\n                    break;\n                }\n            }\n        }\n\n        return result;\n    }\n\n    struct handle_data\n    {\n        unsigned long process_id;\n        HWND window_handle;\n    };\n\n    // used for reactivating a window for a program we already started.\n    HWND FindMainWindow(unsigned long process_id, const bool allowNonVisible)\n    {\n        handle_data data;\n        data.process_id = process_id;\n        data.window_handle = 0;\n\n        if (allowNonVisible)\n        {\n            EnumWindows(EnumWindowsCallbackAllowNonVisible, reinterpret_cast<LPARAM>(&data));\n        }\n        else\n        {\n            EnumWindows(EnumWindowsCallback, reinterpret_cast<LPARAM>(&data));\n        }\n\n        return data.window_handle;\n    }\n\n    // used by FindMainWindow\n    BOOL CALLBACK EnumWindowsCallbackAllowNonVisible(HWND handle, LPARAM lParam)\n    {\n        handle_data& data = *reinterpret_cast<handle_data*>(lParam);\n        unsigned long process_id = 0;\n        GetWindowThreadProcessId(handle, &process_id);\n\n        if (data.process_id == process_id)\n        {\n            data.window_handle = handle;\n            return FALSE;\n        }\n        return TRUE;\n    }\n\n    // used by FindMainWindow\n    BOOL CALLBACK EnumWindowsCallback(HWND handle, LPARAM lParam)\n    {\n        handle_data& data = *reinterpret_cast<handle_data*>(lParam);\n        unsigned long process_id = 0;\n        GetWindowThreadProcessId(handle, &process_id);\n\n        if (data.process_id != process_id || !(GetWindow(handle, GW_OWNER) == static_cast<HWND>(0) && IsWindowVisible(handle)))\n        {\n            return TRUE;\n        }\n\n        data.window_handle = handle;\n        return FALSE;\n    }\n\n    // GetProcessIdByName also used by HandleCreateProcessHotKeysAndChords\n\n    std::vector<DWORD> GetProcessesIdByName(const std::wstring& processName)\n    {\n        std::vector<DWORD> processIds;\n        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n\n        if (snapshot != INVALID_HANDLE_VALUE)\n        {\n            PROCESSENTRY32 processEntry;\n            processEntry.dwSize = sizeof(PROCESSENTRY32);\n\n            if (Process32First(snapshot, &processEntry))\n            {\n                do\n                {\n                    if (_wcsicmp(processEntry.szExeFile, processName.c_str()) == 0)\n                    {\n                        processIds.push_back(processEntry.th32ProcessID);\n                    }\n                } while (Process32Next(snapshot, &processEntry));\n            }\n\n            CloseHandle(snapshot);\n        }\n\n        return processIds;\n    }\n\n    DWORD GetProcessIdByName(const std::wstring& processName)\n    {\n        DWORD pid = 0;\n        HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);\n\n        if (snapshot != INVALID_HANDLE_VALUE)\n        {\n            PROCESSENTRY32 processEntry;\n            processEntry.dwSize = sizeof(PROCESSENTRY32);\n\n            if (Process32First(snapshot, &processEntry))\n            {\n                do\n                {\n                    if (_wcsicmp(processEntry.szExeFile, processName.c_str()) == 0)\n                    {\n                        pid = processEntry.th32ProcessID;\n                        break;\n                    }\n                } while (Process32Next(snapshot, &processEntry));\n            }\n\n            CloseHandle(snapshot);\n        }\n\n        return pid;\n    }\n\n    // Use to find a process by its name\n    std::wstring GetFileNameFromPath(const std::wstring& fullPath)\n    {\n        size_t found = fullPath.find_last_of(L\"\\\\\");\n        if (found != std::wstring::npos)\n        {\n            return fullPath.substr(found + 1);\n        }\n        return fullPath;\n    }\n\n    void toast(param::hstring const& message1, param::hstring const& message2) noexcept\n    {\n        try\n        {\n            // Alternatively can build DOM from code:\n            XmlDocument toastXml;\n            XmlElement toastElement = toastXml.CreateElement(L\"toast\");\n            XmlElement visualElement = toastXml.CreateElement(L\"visual\");\n            XmlElement bindingElement = toastXml.CreateElement(L\"binding\");\n            XmlElement textElement1 = toastXml.CreateElement(L\"text\");\n            XmlElement textElement2 = toastXml.CreateElement(L\"text\");\n\n            toastXml.AppendChild(toastElement);\n            toastElement.AppendChild(visualElement);\n            visualElement.AppendChild(bindingElement);\n\n            bindingElement.AppendChild(textElement1);\n            bindingElement.AppendChild(textElement2);\n\n            bindingElement.SetAttribute(L\"template\", L\"ToastGeneric\");\n\n            textElement1.InnerText(message1);\n            textElement2.InnerText(message2);\n\n            Logger::trace(L\"ChordKeyboardHandler:toastXml {}\", toastXml.GetXml());\n            std::wstring APPLICATION_ID = L\"Microsoft.PowerToysWin32\";\n            const auto notifier = ToastNotificationManager::ToastNotificationManager::CreateToastNotifier(APPLICATION_ID);\n\n            ToastNotification notification{ toastXml };\n            notifier.Show(notification);\n        }\n        catch (...)\n        {\n        }\n\n        /*std::thread{ [message] {\n    \n        } }.detach();*/\n    }\n\n    void CreateOrShowProcessForShortcut(Shortcut shortcut) noexcept\n    {\n        WCHAR fullExpandedFilePath[MAX_PATH];\n        DWORD result = ExpandEnvironmentStrings(shortcut.runProgramFilePath.c_str(), fullExpandedFilePath, MAX_PATH);\n\n        auto fileNamePart = GetFileNameFromPath(fullExpandedFilePath);\n\n        Logger::trace(L\"ChordKeyboardHandler:{}, trying to run {}\", fileNamePart, fullExpandedFilePath);\n        //lastKeyInChord = 0;\n\n        DWORD targetPid = GetProcessIdByName(fileNamePart);\n\n        /*if (fileNamePart != L\"explorer.exe\" && fileNamePart != L\"powershell.exe\" && fileNamePart != L\"cmd.exe\" && fileNamePart != L\"msedge.exe\")\n        {\n            targetPid = GetProcessIdByName(fileNamePart);\n        }*/\n\n        Logger::trace(L\"ChordKeyboardHandler:{}, already running, pid:{}, alreadyRunningAction:{}\", fileNamePart, targetPid, shortcut.alreadyRunningAction);\n\n        if (targetPid != 0 && shortcut.alreadyRunningAction != Shortcut::ProgramAlreadyRunningAction::StartAnother)\n        {\n            if (shortcut.alreadyRunningAction == Shortcut::ProgramAlreadyRunningAction::EndTask)\n            {\n                TerminateProcessesByName(fileNamePart);\n                return;\n            }\n            else if (shortcut.alreadyRunningAction == Shortcut::ProgramAlreadyRunningAction::Close)\n            {\n                CloseProcessByName(fileNamePart);\n                Logger::trace(L\"ChordKeyboardHandler:{}, CloseProcessByName returning 3\", fileNamePart);\n                return;\n            }\n            else if (shortcut.alreadyRunningAction == Shortcut::ProgramAlreadyRunningAction::ShowWindow)\n            {\n                auto processIds = GetProcessesIdByName(fileNamePart);\n\n                for (DWORD pid : processIds)\n                {\n                    ShowProgram(targetPid, fileNamePart, false, false, 0);\n                }\n\n                //if (!ShowProgram(targetPid, fileNamePart, false, false, 0))\n                //{\n                //    /*auto future = std::async(std::launch::async, [=] {\n                //    std::this_thread::sleep_for(std::chrono::milliseconds(30));\n                //    Logger::trace(L\"ChordKeyboardHandler:{}, second try, pid:{}\", fileNamePart, targetPid);\n                //    ShowProgram(targetPid, fileNamePart, false, false);\n                //});*/\n                //}\n                return;\n            }\n        }\n        else\n        {\n            DWORD dwAttrib = GetFileAttributesW(fullExpandedFilePath);\n\n            if (dwAttrib == INVALID_FILE_ATTRIBUTES)\n            {\n                std::wstring title = fmt::format(L\"无法运行 {}\", fileNamePart);\n                std::wstring message = fmt::format(L\"找不到该程序。\");\n                toast(title, message);\n                return;\n            }\n\n            std::wstring expandedArgs;\n            DWORD dwSize = ExpandEnvironmentStrings(shortcut.runProgramArgs.c_str(), nullptr, 0);\n            expandedArgs.resize(dwSize);\n            DWORD result = ExpandEnvironmentStrings(shortcut.runProgramArgs.c_str(), expandedArgs.data(), dwSize);\n\n            WCHAR currentDir[MAX_PATH];\n            WCHAR* currentDirPtr = currentDir;\n            result = ExpandEnvironmentStrings(shortcut.runProgramStartInDir.c_str(), currentDir, MAX_PATH);\n\n            if (shortcut.runProgramStartInDir == L\"\")\n            {\n                currentDirPtr = nullptr;\n            }\n            else\n            {\n                DWORD dwAttrib = GetFileAttributesW(currentDir);\n\n                if (dwAttrib == INVALID_FILE_ATTRIBUTES)\n                {\n                    std::wstring title = fmt::format(L\"无法运行 {}\", fileNamePart);\n                    std::wstring message = fmt::format(L\"起始目录无效。\", currentDir);\n                    currentDirPtr = nullptr;\n                    toast(title, message);\n                    return;\n                }\n            }\n\n            DWORD processId = 0;\n            HANDLE newProcessHandle;\n\n            if (shortcut.elevationLevel == Shortcut::ElevationLevel::Elevated)\n            {\n                newProcessHandle = run_elevated(fullExpandedFilePath, expandedArgs, currentDirPtr, (shortcut.startWindowType == Shortcut::StartWindowType::Normal));\n                processId = GetProcessId(newProcessHandle);\n            }\n            else if (shortcut.elevationLevel == Shortcut::ElevationLevel::NonElevated)\n            {\n                run_non_elevated(fullExpandedFilePath, expandedArgs, &processId, currentDirPtr, (shortcut.startWindowType == Shortcut::StartWindowType::Normal));\n            }\n            else if (shortcut.elevationLevel == Shortcut::ElevationLevel::DifferentUser)\n            {\n                newProcessHandle = run_as_different_user(fullExpandedFilePath, expandedArgs, currentDirPtr, (shortcut.startWindowType == Shortcut::StartWindowType::Normal));\n                processId = GetProcessId(newProcessHandle);\n            }\n\n            if (processId == 0)\n            {\n                std::wstring title = fmt::format(L\"无法运行 {}\", fileNamePart);\n                std::wstring message = fmt::format(L\"程序可能启动失败了。\");\n                toast(title, message);\n                return;\n            }\n\n            if (shortcut.startWindowType == Shortcut::StartWindowType::Hidden)\n            {\n                HideProgram(processId, fileNamePart, 0);\n            }\n            //ShowProgram(processId, fileNamePart, true, false, (shortcut.startWindowType == Shortcut::StartWindowType::Hidden), 0);\n        }\n        return;\n    }\n\n    void CloseProcessByName(const std::wstring& fileNamePart)\n    {\n        auto processIds = GetProcessesIdByName(fileNamePart);\n\n        if (processIds.size() == 0)\n        {\n            Logger::trace(L\"ChordKeyboardHandler:{}, Nothing To WM_CLOSE\", fileNamePart);\n            return;\n        }\n\n        auto threadFunction = [fileNamePart]() {\n            auto processIds = GetProcessesIdByName(fileNamePart);\n            auto retryCount = 10;\n            while (processIds.size() > 0 && retryCount-- > 0)\n            {\n                //Logger::trace(L\"ChordKeyboardHandler:{}, WM_CLOSE 'ing {}processIds \", fileNamePart, processIds.size());\n                for (DWORD pid : processIds)\n                {\n                    //Logger::trace(L\"ChordKeyboardHandler:{}, WM_CLOSE ({}) -> pid:{}\", fileNamePart, retryCount, pid);\n                    HWND hwnd = FindMainWindow(pid, false);\n                    SendMessage(hwnd, WM_CLOSE, 0, 0);\n\n                    // small sleep between when there are a lot might help\n                    Sleep(10);\n                }\n\n                processIds = GetProcessesIdByName(fileNamePart);\n                if (processIds.size() <= 0)\n                {\n                    Logger::trace(L\"ChordKeyboardHandler:{}, WM_CLOSE done\", fileNamePart);\n                    break;\n                }\n                else\n                {\n                    Sleep(100);\n                }\n            }\n        };\n\n        processIds = GetProcessesIdByName(fileNamePart);\n\n        if (processIds.size() > 0)\n        {\n            std::thread myThread(threadFunction);\n            if (myThread.joinable())\n            {\n                myThread.detach();\n            }\n        }\n\n        Logger::trace(L\"ChordKeyboardHandler:{}, CloseProcessByName returning\", fileNamePart);\n    }\n\n    void TerminateProcessesByName(const std::wstring& fileNamePart)\n    {\n        auto processIds = GetProcessesIdByName(fileNamePart);\n\n        if (processIds.size() == 0)\n        {\n            Logger::trace(L\"ChordKeyboardHandler:{}, Nothing To PROCESS_TERMINATE\", fileNamePart);\n            return;\n        }\n\n        for (DWORD pid : processIds)\n        {\n            HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);\n            Logger::trace(L\"ChordKeyboardHandler:{}, PROCESS_TERMINATE (1) -> pid:{}\", fileNamePart, pid);\n            if (hProcess != NULL)\n            {\n                if (!TerminateProcess(hProcess, 0))\n                {\n                    CloseHandle(hProcess);\n                }\n                else\n                {\n                    CloseHandle(hProcess);\n                }\n            }\n        }\n    }\n\n    bool HideProgram(DWORD pid, std::wstring programName, int retryCount)\n    {\n        Logger::trace(L\"ChordKeyboardHandler:HideProgram starting with {},{}, retryCount:{}\", pid, programName, retryCount);\n\n        HWND hwnd = FindMainWindow(pid, false);\n        if (hwnd == NULL)\n        {\n            if (retryCount < 20)\n            {\n                Logger::trace(L\"ChordKeyboardHandler:hwnd not found will retry for pid:{}\", pid);\n                auto future = std::async(std::launch::async, [=] {\n                    std::this_thread::sleep_for(std::chrono::milliseconds(50));\n                    auto result = HideProgram(pid, programName, retryCount + 1);\n                    return false;\n                });\n            }\n        }\n\n        hwnd = FindWindow(nullptr, nullptr);\n\n        auto anyHideResultFailed = false;\n\n        Logger::trace(L\"ChordKeyboardHandler:{}:{},{}, FindWindow, HideProgram (all)\", programName, pid, retryCount);\n        while (hwnd)\n        {\n            DWORD pidForHwnd;\n            GetWindowThreadProcessId(hwnd, &pidForHwnd);\n            if (pid == pidForHwnd)\n            {\n                if (IsWindowVisible(hwnd))\n                {\n                    ShowWindow(hwnd, SW_HIDE);\n                    Logger::trace(L\"ChordKeyboardHandler:{}, tryToHide {}, {}\", programName, reinterpret_cast<uintptr_t>(hwnd), anyHideResultFailed);\n                }\n            }\n            hwnd = FindWindowEx(NULL, hwnd, NULL, NULL);\n        }\n\n        return true;\n    }\n\n    bool ShowProgram(DWORD pid, std::wstring programName, bool isNewProcess, bool minimizeIfVisible, int retryCount)\n    {\n        Logger::trace(L\"ChordKeyboardHandler:ShowProgram starting with {},{},isNewProcess:{}, tryToHide:{} retryCount:{}\", pid, programName, isNewProcess, retryCount);\n\n        // a good place to look for this...\n        // https://github.com/ritchielawrence/cmdow\n\n        // try by main window.\n        auto allowNonVisible = false;\n\n        HWND hwnd = FindMainWindow(pid, allowNonVisible);\n\n        if (hwnd == NULL)\n        {\n            if (retryCount < 20)\n            {\n                Logger::trace(L\"ChordKeyboardHandler:hwnd not found will retry for pid:{}, allowNonVisible:{}\", pid, allowNonVisible);\n\n                auto future = std::async(std::launch::async, [=] {\n                    std::this_thread::sleep_for(std::chrono::milliseconds(50));\n                    auto result = ShowProgram(pid, programName, isNewProcess, minimizeIfVisible, retryCount + 1);\n                    return false;\n                });\n            }\n        }\n        else\n        {\n            Logger::trace(L\"ChordKeyboardHandler:{}, got hwnd from FindMainWindow\", programName);\n\n            if (hwnd == GetForegroundWindow())\n            {\n                // only hide if this was a call from a already open program, don't make small if we just opened it.\n                if (!isNewProcess && minimizeIfVisible)\n                {\n                    Logger::trace(L\"ChordKeyboardHandler:{}, got GetForegroundWindow, doing SW_MINIMIZE\", programName);\n                    return ShowWindow(hwnd, SW_MINIMIZE);\n                }\n                return false;\n            }\n            else\n            {\n                Logger::trace(L\"ChordKeyboardHandler:{}, not ForegroundWindow, doing SW_RESTORE\", programName);\n\n                // Check if the window is minimized\n                if (IsIconic(hwnd))\n                {\n                    // Show the window since SetForegroundWindow fails on minimized windows\n                    if (!ShowWindow(hwnd, SW_RESTORE))\n                    {\n                        Logger::error(L\"ShowWindow failed\");\n                    }\n                }\n\n                INPUT inputs[1] = { { .type = INPUT_MOUSE } };\n                SendInput(ARRAYSIZE(inputs), inputs, sizeof(INPUT));\n\n                if (!SetForegroundWindow(hwnd))\n                {\n                    auto errorCode = GetLastError();\n                    Logger::warn(L\"ChordKeyboardHandler:{}, failed to SetForegroundWindow, {}\", programName, errorCode);\n                    return false;\n                }\n                else\n                {\n                    Logger::trace(L\"ChordKeyboardHandler:{}, success on SetForegroundWindow\", programName);\n                    return true;\n                }\n            }\n        }\n\n        if (isNewProcess)\n        {\n            return true;\n        }\n\n        if (false)\n        {\n            // try by console.\n            hwnd = FindWindow(nullptr, nullptr);\n            if (AttachConsole(pid))\n            {\n                Logger::trace(L\"ChordKeyboardHandler:{}, success on AttachConsole\", programName);\n\n                // Get the console window handle\n                hwnd = GetConsoleWindow();\n                auto showByConsoleSuccess = false;\n                if (hwnd != NULL)\n                {\n                    Logger::trace(L\"ChordKeyboardHandler:{}, success on GetConsoleWindow, doing SW_RESTORE\", programName);\n\n                    ShowWindow(hwnd, SW_RESTORE);\n\n                    if (!SetForegroundWindow(hwnd))\n                    {\n                        auto errorCode = GetLastError();\n                        Logger::warn(L\"ChordKeyboardHandler:{}, failed to SetForegroundWindow, {}\", programName, errorCode);\n                    }\n                    else\n                    {\n                        Logger::trace(L\"ChordKeyboardHandler:{}, success on SetForegroundWindow\", programName);\n                        showByConsoleSuccess = true;\n                    }\n                }\n\n                // Detach from the console\n                FreeConsole();\n                if (showByConsoleSuccess)\n                {\n                    return true;\n                }\n            }\n        }\n\n        // try to just show them all (if they have a title)!.\n        hwnd = FindWindow(nullptr, nullptr);\n\n        auto anyHideResultFailed = false;\n        if (hwnd)\n        {\n            Logger::trace(L\"ChordKeyboardHandler:{}:{},{}, FindWindow (show all mode)\", programName, pid, retryCount);\n            while (hwnd)\n            {\n                DWORD pidForHwnd;\n                GetWindowThreadProcessId(hwnd, &pidForHwnd);\n                if (pid == pidForHwnd)\n                {\n                    int length = GetWindowTextLength(hwnd);\n\n                    if (length > 0)\n                    {\n                        ShowWindow(hwnd, SW_RESTORE);\n\n                        // hwnd is the window handle with targetPid\n                        if (SetForegroundWindow(hwnd))\n                        {\n                            Logger::trace(L\"ChordKeyboardHandler:{}, success on SetForegroundWindow\", programName);\n                            return true;\n                        }\n                        else\n                        {\n                            auto errorCode = GetLastError();\n                            Logger::warn(L\"ChordKeyboardHandler:{}, failed to SetForegroundWindow, {}\", programName, errorCode);\n                        }\n                    }\n                }\n                hwnd = FindWindowEx(NULL, hwnd, NULL, NULL);\n            }\n        }\n\n        return false;\n    }\n\n    // Function to a handle an os-level shortcut remap\n    intptr_t HandleOSLevelShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept\n    {\n        // Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.\n        if (data->lParam->dwExtraInfo != KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG)\n        {\n            bool result = HandleShortcutRemapEvent(ii, data, state);\n            return result;\n        }\n\n        return 0;\n    }\n\n    // Function to a handle an app-specific shortcut remap\n    intptr_t HandleAppSpecificShortcutRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state) noexcept\n    {\n        // Check if the key event was generated by KeyboardManager to avoid remapping events generated by us.\n        if (data->lParam->dwExtraInfo != KeyboardManagerConstants::KEYBOARDMANAGER_SHORTCUT_FLAG)\n        {\n            std::wstring process_name;\n\n            // Allocate MAX_PATH amount of memory\n            process_name.resize(MAX_PATH);\n            ii.GetForegroundProcess(process_name);\n\n            // Remove elements after null character\n            process_name.erase(std::find(process_name.begin(), process_name.end(), L'\\0'), process_name.end());\n\n            if (process_name.empty())\n            {\n                return 0;\n            }\n\n            // Convert process name to lower case\n            std::transform(process_name.begin(), process_name.end(), process_name.begin(), towlower);\n\n            std::wstring query_string;\n\n            AppSpecificShortcutRemapTable::iterator it;\n\n            // Check if an app-specific shortcut is already activated\n            if (state.GetActivatedApp() == KeyboardManagerConstants::NoActivatedApp)\n            {\n                query_string = process_name;\n                it = state.appSpecificShortcutReMap.find(query_string);\n\n                // If no entry is found, search for the process name without its file extension\n                if (it == state.appSpecificShortcutReMap.end())\n                {\n                    // Find index of the file extension\n                    size_t extensionIndex = process_name.find_last_of(L\".\");\n                    query_string = process_name.substr(0, extensionIndex);\n                    it = state.appSpecificShortcutReMap.find(query_string);\n                }\n            }\n            else\n            {\n                query_string = state.GetActivatedApp();\n                it = state.appSpecificShortcutReMap.find(query_string);\n            }\n\n            if (it != state.appSpecificShortcutReMap.end())\n            {\n                bool result = HandleShortcutRemapEvent(ii, data, state, query_string);\n                return result;\n            }\n        }\n\n        return 0;\n    }\n\n    // Function to ensure Ctrl/Shift/Alt modifier key state is not detected as pressed down by applications which detect keys at a lower level than hooks when it is remapped for scenarios where its required\n    void ResetIfModifierKeyForLowerLevelKeyHandlers(KeyboardManagerInput::InputInterface& ii, DWORD key, DWORD target)\n    {\n        // If the target is Caps Lock and the other key is either Ctrl/Alt/Shift then reset the modifier state to lower level handlers\n        if (target == VK_CAPITAL)\n        {\n            // If the argument is either of the Ctrl/Shift/Alt modifier key codes\n            if (Helpers::IsModifierKey(key) && !(key == VK_LWIN || key == VK_RWIN || key == CommonSharedConstants::VK_WIN_BOTH))\n            {\n                std::vector<INPUT> keyEventList;\n\n                // Use the suppress flag to ensure these are not intercepted by any remapped keys or shortcuts\n                Helpers::SetKeyEvent(keyEventList, INPUT_KEYBOARD, static_cast<WORD>(key), KEYEVENTF_KEYUP, KeyboardManagerConstants::KEYBOARDMANAGER_SUPPRESS_FLAG);\n                ii.SendVirtualInput(keyEventList);\n            }\n        }\n    }\n\n    // Function to generate a unicode string in response to a single keypress\n    intptr_t HandleSingleKeyToTextRemapEvent(KeyboardManagerInput::InputInterface& ii, LowlevelKeyboardEvent* data, State& state)\n    {\n        if (GeneratedByKBM(data))\n        {\n            return 0;\n        }\n\n        // Only send the text on keydown event\n        if (data->wParam != WM_KEYDOWN)\n        {\n            return 0;\n        }\n\n        const auto remapping = state.GetSingleKeyToTextRemapEvent(data->lParam->vkCode);\n        if (!remapping)\n        {\n            return 0;\n        }\n\n        std::vector<INPUT> keyEventList;\n        Helpers::SetTextKeyEvents(keyEventList, *remapping);\n        ii.SendVirtualInput(keyEventList);\n\n        return 1;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/InputInterpreter.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text.RegularExpressions;\n\nusing UnitsNet;\nusing Wox.Plugin;\n\nnamespace Community.PowerToys.Run.Plugin.UnitConverter\n{\n    public static class InputInterpreter\n    {\n        private static readonly string Pattern = @\"(?<=\\d)(?![,.\\-])(?=[\\D])|(?<=[\\D])(?<![,.\\-])(?=\\d)\";\n\n        public static string[] RegexSplitter(string[] split)\n        {\n            return Regex.Split(split[0], Pattern);\n        }\n\n        /// <summary>\n        /// Separates input like: \"1ft in cm\" to \"1 ft in cm\"\n        /// </summary>\n        public static void InputSpaceInserter(ref string[] split)\n        {\n            if (split.Length != 3)\n            {\n                return;\n            }\n\n            string[] parseInputWithoutSpace = Regex.Split(split[0], Pattern);\n\n            if (parseInputWithoutSpace.Length > 1)\n            {\n                string[] firstEntryRemoved = split.Skip(1).ToArray();\n                string[] newSplit = new string[] { parseInputWithoutSpace[0], parseInputWithoutSpace[1] };\n\n                split = newSplit.Concat(firstEntryRemoved).ToArray();\n            }\n        }\n\n        /// <summary>\n        /// Replaces a split input array with shorthand feet/inch notation (1', 1'2\" etc) to 'x foot in cm'.\n        /// </summary>\n        public static void ShorthandFeetInchHandler(ref string[] split, CultureInfo culture)\n        {\n            if (!split[0].Contains('\\'') && !split[0].Contains('\\\"'))\n            {\n                return;\n            }\n\n            // catches 1' || 1\" || 1'2 || 1'2\" in cm\n            // by converting it to \"x foot in cm\"\n            if (split.Length == 3)\n            {\n                string[] shortsplit = RegexSplitter(split);\n\n                switch (shortsplit.Length)\n                {\n                    case 2:\n                        // ex: 1' & 1\"\n                        if (shortsplit[1] == \"\\'\")\n                        {\n                            string[] newInput = new string[] { shortsplit[0], \"foot\", split[1], split[2] };\n                            split = newInput;\n                        }\n                        else if (shortsplit[1] == \"\\\"\")\n                        {\n                            string[] newInput = new string[] { shortsplit[0], \"inch\", split[1], split[2] };\n                            split = newInput;\n                        }\n\n                        break;\n\n                    case 3:\n                    case 4:\n                        // ex: 1'2 and 1'2\"\n                        if (shortsplit[1] == \"\\'\")\n                        {\n                            bool isNegative = shortsplit[0].StartsWith('-');\n                            if (isNegative)\n                            {\n                                shortsplit[0] = shortsplit[0].Remove(0, 1);\n                            }\n\n                            bool isFeet = double.TryParse(shortsplit[0], NumberStyles.AllowDecimalPoint, culture, out double feet);\n                            bool isInches = double.TryParse(shortsplit[2], NumberStyles.AllowDecimalPoint, culture, out double inches);\n\n                            if (!isFeet || !isInches)\n                            {\n                                // at least one could not be parsed correctly\n                                break;\n                            }\n\n                            double convertedTotalInFeet = Length.FromFeetInches(feet, inches).Feet;\n                            if (isNegative)\n                            {\n                                convertedTotalInFeet *= -1;\n                            }\n\n                            string[] newInput = new string[] { convertedTotalInFeet.ToString(culture), \"foot\", split[1], split[2] };\n                            split = newInput;\n                        }\n\n                        break;\n\n                    default:\n                        break;\n                }\n            }\n        }\n\n        /// <summary>\n        /// Adds degree prefixes to degree units for shorthand notation. E.g. '10 c in fahrenheit' becomes '10 °C in DegreeFahrenheit'.\n        /// </summary>\n        public static void DegreePrefixer(ref string[] split)\n        {\n            switch (split[1].ToLower(CultureInfo.CurrentCulture))\n            {\n                case \"celsius\":\n                    split[1] = \"DegreeCelsius\";\n                    break;\n\n                case \"fahrenheit\":\n                    split[1] = \"DegreeFahrenheit\";\n                    break;\n\n                case \"c\":\n                    split[1] = \"°C\";\n                    break;\n\n                case \"f\":\n                    split[1] = \"°F\";\n                    break;\n\n                default:\n                    break;\n            }\n\n            switch (split[3].ToLower(CultureInfo.CurrentCulture))\n            {\n                case \"celsius\":\n                    split[3] = \"DegreeCelsius\";\n                    break;\n\n                case \"fahrenheit\":\n                    split[3] = \"DegreeFahrenheit\";\n                    break;\n\n                case \"c\":\n                    split[3] = \"°C\";\n                    break;\n\n                case \"f\":\n                    split[3] = \"°F\";\n                    break;\n\n                default:\n                    break;\n            }\n\n#pragma warning disable SA1501 // Statement should not be on a single line\n            // [Chinese Translator]\n            // 前面的单位\n            // Acceleration 加速度    【自由，无互相冲突】（其他单位由长度、时间合成）\n            split[1] = split[1].Replace(\"标准重力\", \"g\");\n\n            // Energy 能量    在时间前（马力时 冲突 时），在质量前（磅力 冲突）\n            split[1] = split[1].Replace(\"焦耳\", \"J\").Replace(\"焦\", \"J\").Replace(\"卡路里\", \"cal\").Replace(\"卡\", \"cal\").Replace(\"英国热力单位\", \"BTU\").Replace(\"英热\", \"BTU\").Replace(\"电子伏特\", \"eV\").Replace(\"磅力\", \"ft·lb\").Replace(\"尔格\", \"erg\").Replace(\"马力时\", \"hp·h\");\n\n            // Power 功率    【自由，无互相冲突】\n            split[1] = split[1].Replace(\"瓦特\", \"W\").Replace(\"瓦\", \"W\").Replace(\"机械马力\", \"hp(I)\").Replace(\"公制马力\", \"hp(M)\").Replace(\"电气马力\", \"hp(E)\").Replace(\"锅炉马力\", \"hp(S)\").Replace(\"液压马力\", \"hp(H)\").Replace(\"马力\", \"hp(M)\").Replace(\"匹\", \"hp(M)\");\n\n            // Angle 角度    【自由，无互相冲突】\n            if (split[1] == \"度\") { split[1] = \"deg\"; }\n            if (split[1] == \"分\") { split[1] = \"min\"; }\n            if (split[1] == \"秒\") { split[1] = \"sec\"; }\n            split[1] = split[1].Replace(\"弧度\", \"rad\").Replace(\"百分度\", \"gradian\").Replace(\"圈\", \"r\").Replace(\"转\", \"r\");\n\n            // Duration 时间    在角度后（分秒 分类讨论）\n            split[1] = split[1].Replace(\"年\", \"yr\").Replace(\"月\", \"mo\").Replace(\"星期\", \"week\").Replace(\"周\", \"week\").Replace(\"日\", \"d\").Replace(\"天\", \"d\").Replace(\"小时\", \"h\").Replace(\"时\", \"h\").Replace(\"分钟\", \"min\").Replace(\"分\", \"min\").Replace(\"秒钟\", \"s\").Replace(\"秒\", \"s\");\n\n            // Temperature 温度    在体积前（标 修补器 冲突 温标），在角度后（度 冲突 度 修补器）\n            if (split[1].Contains(\"温标\")) { split[1] = \"°\" + split[1].Replace(\"温标\", string.Empty); }\n            if (split[1].Contains(\"温度\")) { split[1] = \"°\" + split[1].Replace(\"温度\", string.Empty); }\n            if (split[1].Contains('度')) { split[1] = \"°\" + split[1].Replace(\"度\", string.Empty); }\n            split[1] = split[1].Replace(\"开尔文\", \"K\").Replace(\"开\", \"K\").Replace(\"°K\", \"K\").Replace(\"摄尔修斯\", \"C\").Replace(\"摄氏\", \"C\").Replace(\"℃\", \"°C\").Replace(\"德利尔\", \"De\").Replace(\"德氏\", \"De\").Replace(\"华伦海特\", \"F\").Replace(\"华氏\", \"F\").Replace(\"℉\", \"°F\").Replace(\"牛顿\", \"N\").Replace(\"牛\", \"N\").Replace(\"兰金\", \"R\").Replace(\"兰氏\", \"R\").Replace(\"列奥缪尔\", \"Ré\").Replace(\"列氏\", \"Ré\").Replace(\"罗默\", \"Rø\").Replace(\"罗氏\", \"Rø\").Replace(\"氏\", string.Empty).Replace(\"°太阳\", \"T⊙\");\n\n            // Pressure 压强    在能量后（磅力 修补器 依赖），在能量、功率后（力 冲突 马力、马力时，帕斯卡 修补器 依赖 卡），在体积前（标准大气压 冲突 标 修补器）（质量 千克公斤吨+力 合成）（长度 毫米+汞柱 合成）（温度 牛+每+米+方 合成）\n            split[1] = split[1].Replace(\"帕斯cal\", \"Pa\").Replace(\"帕\", \"Pa\").Replace(\"标准大气压\", \"atm\").Replace(\"工程大气压\", \"at\").Replace(\"大气压\", \"atm\").Replace(\"巴\", \"bar\").Replace(\"千ft·lb每\", \"kipf/\").Replace(\"ft·lb每\", \"lb/\").Replace(\"力\", \"f\").Replace(\"达因\", \"dyn\").Replace(\"托\", \"torr\").Replace(\"汞柱\", \"Hg\").Replace(\"英寸水柱\", \"wc\");\n            if (split[1].Contains(\"扬程\")) { split[1] = split[1].Replace(\"扬程\", string.Empty) + \" of head\"; }\n\n            // Volume 体积    在面积、长度前（英亩英尺 板英尺 冲突）\n            split[1] = split[1].Replace(\"公升\", \"L\").Replace(\"立升\", \"L\").Replace(\"升\", \"L\").Replace(\"勺\", \"匙\").Replace(\"式\", \"制\").Replace(\"标\", \"制\").Replace(\"英液加仑\", \"ImperialGallon\").Replace(\"英液盎司\", \"ImperialOunce\").Replace(\"美液加仑\", \"UsGallon\").Replace(\"美液盎司\", \"UsOunce\").Replace(\"美制汤匙\", \"UsTablespoon\").Replace(\"澳制汤匙\", \"AuTablespoon\").Replace(\"英制汤匙\", \"UkTablespoon\").Replace(\"公制茶匙\", \"MetricTeaspoon\").Replace(\"美制茶匙\", \"UsTeaspoon\").Replace(\"公制杯\", \"MetricCup\").Replace(\"美制市杯\", \"UsCustomaryCup\").Replace(\"美制法杯\", \"UsLegalCup\").Replace(\"桶油当量\", \"bbl\").Replace(\"美制酒桶\", \"UsBeerBarrel\").Replace(\"英制酒桶\", \"ImperialBeerBarrel\").Replace(\"美制夸脱\", \"UsQuart\").Replace(\"美制品脱\", \"UsPint\").Replace(\"英亩英尺\", \"ac-ft\").Replace(\"英制品脱\", \"pt\").Replace(\"品脱\", \"pt\").Replace(\"板英尺\", \"bf\");\n\n            // Area 面积    在长度前（平方海里 冲突）（其他单位由长度合成）\n            split[1] = split[1].Replace(\"英亩\", \"ac\").Replace(\"公顷\", \"ha\").Replace(\"平方海里\", \"nmi²\");\n\n            // Length 长度    在时间后（天文单位 修补器 依赖 天）\n            split[1] = split[1].Replace(\"米\", \"m\").Replace(\"公里\", \"km\").Replace(\"公尺\", \"m\").Replace(\"公寸\", \"dm\").Replace(\"公分\", \"cm\").Replace(\"公厘\", \"mm\").Replace(\"英里\", \"mi\").Replace(\"码\", \"yd\").Replace(\"英尺\", \"ft\").Replace(\"英寸\", \"in\").Replace(\"密耳\", \"mil\").Replace(\"海里\", \"NM\").Replace(\"英寻\", \"fathom\").Replace(\"缆索\", \"shackle\").Replace(\"缆\", \"shackle\").Replace(\"缇\", \"twip\").Replace(\"掌\", \"hand\").Replace(\"d文单位\", \"au\").Replace(\"派卡\", \"pc\").Replace(\"光年\", \"ly\").Replace(\"太阳半径\", \"R⊙\").Replace(\"链\", \"ch\");\n\n            // Mass 质量    自由\n            split[1] = split[1].Replace(\"克\", \"g\").Replace(\"公斤\", \"kg\").Replace(\"短吨\", \"short tn\").Replace(\"长吨\", \"long tn\").Replace(\"吨\", \"t\").Replace(\"磅\", \"lb\").Replace(\"盎司\", \"oz\").Replace(\"斯勒格\", \"slug\").Replace(\"石\", \"st\").Replace(\"格令\", \"gr\").Replace(\"太阳质量\", \"M⊙\").Replace(\"地球质量\", \"em\");\n\n            // Information 数据    在速度前（节 冲突 字节），在能量、长度后（xx单位 冲突 位）\n            split[1] = split[1].Replace(\"字节\", \"B\").Replace(\"位\", \"b\").Replace(\"比特\", \"b\");\n\n            // Speed 速度    在长度、时间后（修补器 处理依赖），在数据后（节 冲突 字节）\n            split[1] = split[1].Replace(\"节\", \"kn\").Replace(\"mi每h\", \"mph\").Replace(\"mi/h\", \"mph\");\n\n            // 通用    最后\n            if (split[1].Contains(\"平方\")) { split[1] = split[1].Replace(\"平方\", string.Empty) + \"²\"; }\n            if (split[1].Contains(\"二次方\")) { split[1] = split[1].Replace(\"二次方\", string.Empty) + \"²\"; }\n            if (split[1].Contains(\"立方\")) { split[1] = split[1].Replace(\"立方\", string.Empty) + \"³\"; }\n            if (split[1].Contains(\"三次方\")) { split[1] = split[1].Replace(\"三次方\", string.Empty) + \"³\"; }\n            if (split[1].Contains('方')) { split[1] = split[1].Replace(\"方\", string.Empty) + \"²\"; }\n            split[1] = split[1].Replace(\"艾\", \"E\").Replace(\"拍\", \"P\").Replace(\"太\", \"T\").Replace(\"吉\", \"G\").Replace(\"兆\", \"M\").Replace(\"千\", \"k\").Replace(\"百\", \"h\").Replace(\"分\", \"d\").Replace(\"厘\", \"c\").Replace(\"毫\", \"m\").Replace(\"微\", \"μ\").Replace(\"纳\", \"n\");\n            split[1] = split[1].Replace(\"的\", string.Empty).Replace(\"个\", string.Empty).Replace(\"每\", \"/\");\n\n            // 后面的单位\n            // Acceleration 加速度    【自由，无互相冲突】（其他单位由长度、时间合成）\n            split[3] = split[3].Replace(\"标准重力\", \"g\");\n\n            // Energy 能量    在时间前（马力时 冲突 时），在质量前（磅力 冲突）\n            split[3] = split[3].Replace(\"焦耳\", \"J\").Replace(\"焦\", \"J\").Replace(\"卡路里\", \"cal\").Replace(\"卡\", \"cal\").Replace(\"英国热力单位\", \"BTU\").Replace(\"英热\", \"BTU\").Replace(\"电子伏特\", \"eV\").Replace(\"磅力\", \"ft·lb\").Replace(\"尔格\", \"erg\").Replace(\"马力时\", \"hp·h\");\n\n            // Power 功率    【自由，无互相冲突】\n            split[3] = split[3].Replace(\"瓦特\", \"W\").Replace(\"瓦\", \"W\").Replace(\"机械马力\", \"hp(I)\").Replace(\"公制马力\", \"hp(M)\").Replace(\"电气马力\", \"hp(E)\").Replace(\"锅炉马力\", \"hp(S)\").Replace(\"液压马力\", \"hp(H)\").Replace(\"马力\", \"hp(M)\").Replace(\"匹\", \"hp(M)\");\n\n            // Angle 角度    【自由，无互相冲突】\n            if (split[3] == \"度\") { split[3] = \"deg\"; }\n            if (split[3] == \"分\") { split[3] = \"min\"; }\n            if (split[3] == \"秒\") { split[3] = \"sec\"; }\n            split[3] = split[3].Replace(\"弧度\", \"rad\").Replace(\"百分度\", \"gradian\").Replace(\"圈\", \"r\").Replace(\"转\", \"r\");\n\n            // Duration 时间    在角度后（分秒 分类讨论）\n            split[3] = split[3].Replace(\"年\", \"yr\").Replace(\"月\", \"mo\").Replace(\"星期\", \"week\").Replace(\"周\", \"week\").Replace(\"日\", \"d\").Replace(\"天\", \"d\").Replace(\"小时\", \"h\").Replace(\"时\", \"h\").Replace(\"分钟\", \"min\").Replace(\"分\", \"min\").Replace(\"秒钟\", \"s\").Replace(\"秒\", \"s\");\n\n            // Temperature 温度    在体积前（标 修补器 冲突 温标），在角度后（度 冲突 度 修补器）\n            if (split[3].Contains(\"温标\")) { split[3] = \"°\" + split[3].Replace(\"温标\", string.Empty); }\n            if (split[3].Contains(\"温度\")) { split[3] = \"°\" + split[3].Replace(\"温度\", string.Empty); }\n            if (split[3].Contains('度')) { split[3] = \"°\" + split[3].Replace(\"度\", string.Empty); }\n            split[3] = split[3].Replace(\"开尔文\", \"K\").Replace(\"开\", \"K\").Replace(\"°K\", \"K\").Replace(\"摄尔修斯\", \"C\").Replace(\"摄氏\", \"C\").Replace(\"℃\", \"°C\").Replace(\"德利尔\", \"De\").Replace(\"德氏\", \"De\").Replace(\"华伦海特\", \"F\").Replace(\"华氏\", \"F\").Replace(\"℉\", \"°F\").Replace(\"牛顿\", \"N\").Replace(\"牛\", \"N\").Replace(\"兰金\", \"R\").Replace(\"兰氏\", \"R\").Replace(\"列奥缪尔\", \"Ré\").Replace(\"列氏\", \"Ré\").Replace(\"罗默\", \"Rø\").Replace(\"罗氏\", \"Rø\").Replace(\"氏\", string.Empty).Replace(\"°太阳\", \"T⊙\");\n\n            // Pressure 压强    在能量后（磅力 修补器 依赖），在能量、功率后（力 冲突 马力、马力时，帕斯卡 修补器 依赖 卡），在体积前（标准大气压 冲突 标 修补器）（质量 千克公斤吨+力 合成）（长度 毫米+汞柱 合成）（温度 牛+每+米+方 合成）\n            split[3] = split[3].Replace(\"帕斯cal\", \"Pa\").Replace(\"帕\", \"Pa\").Replace(\"标准大气压\", \"atm\").Replace(\"工程大气压\", \"at\").Replace(\"大气压\", \"atm\").Replace(\"巴\", \"bar\").Replace(\"千ft·lb每\", \"kipf/\").Replace(\"ft·lb每\", \"lb/\").Replace(\"力\", \"f\").Replace(\"达因\", \"dyn\").Replace(\"托\", \"torr\").Replace(\"汞柱\", \"Hg\").Replace(\"英寸水柱\", \"wc\");\n            if (split[3].Contains(\"扬程\")) { split[3] = split[3].Replace(\"扬程\", string.Empty) + \" of head\"; }\n\n            // Volume 体积    在面积、长度前（英亩英尺 板英尺 冲突）\n            split[3] = split[3].Replace(\"公升\", \"L\").Replace(\"立升\", \"L\").Replace(\"升\", \"L\").Replace(\"勺\", \"匙\").Replace(\"式\", \"制\").Replace(\"标\", \"制\").Replace(\"英液加仑\", \"ImperialGallon\").Replace(\"英液盎司\", \"ImperialOunce\").Replace(\"美液加仑\", \"UsGallon\").Replace(\"美液盎司\", \"UsOunce\").Replace(\"美制汤匙\", \"UsTablespoon\").Replace(\"澳制汤匙\", \"AuTablespoon\").Replace(\"英制汤匙\", \"UkTablespoon\").Replace(\"公制茶匙\", \"MetricTeaspoon\").Replace(\"美制茶匙\", \"UsTeaspoon\").Replace(\"公制杯\", \"MetricCup\").Replace(\"美制市杯\", \"UsCustomaryCup\").Replace(\"美制法杯\", \"UsLegalCup\").Replace(\"桶油当量\", \"bbl\").Replace(\"美制酒桶\", \"UsBeerBarrel\").Replace(\"英制酒桶\", \"ImperialBeerBarrel\").Replace(\"美制夸脱\", \"UsQuart\").Replace(\"美制品脱\", \"UsPint\").Replace(\"英亩英尺\", \"ac-ft\").Replace(\"英制品脱\", \"pt\").Replace(\"品脱\", \"pt\").Replace(\"板英尺\", \"bf\");\n\n            // Area 面积    在长度前（平方海里 冲突）（其他单位由长度合成）\n            split[3] = split[3].Replace(\"英亩\", \"ac\").Replace(\"公顷\", \"ha\").Replace(\"平方海里\", \"nmi²\");\n\n            // Length 长度    在时间后（天文单位 修补器 依赖 天）\n            split[3] = split[3].Replace(\"米\", \"m\").Replace(\"公里\", \"km\").Replace(\"公尺\", \"m\").Replace(\"公寸\", \"dm\").Replace(\"公分\", \"cm\").Replace(\"公厘\", \"mm\").Replace(\"英里\", \"mi\").Replace(\"码\", \"yd\").Replace(\"英尺\", \"ft\").Replace(\"英寸\", \"in\").Replace(\"密耳\", \"mil\").Replace(\"海里\", \"NM\").Replace(\"英寻\", \"fathom\").Replace(\"缆索\", \"shackle\").Replace(\"缆\", \"shackle\").Replace(\"缇\", \"twip\").Replace(\"掌\", \"hand\").Replace(\"d文单位\", \"au\").Replace(\"派卡\", \"pc\").Replace(\"光年\", \"ly\").Replace(\"太阳半径\", \"R⊙\").Replace(\"链\", \"ch\");\n\n            // Mass 质量    自由\n            split[3] = split[3].Replace(\"克\", \"g\").Replace(\"公斤\", \"kg\").Replace(\"短吨\", \"short tn\").Replace(\"长吨\", \"long tn\").Replace(\"吨\", \"t\").Replace(\"磅\", \"lb\").Replace(\"盎司\", \"oz\").Replace(\"斯勒格\", \"slug\").Replace(\"石\", \"st\").Replace(\"格令\", \"gr\").Replace(\"太阳质量\", \"M⊙\").Replace(\"地球质量\", \"em\");\n\n            // Information 数据    在速度前（节 冲突 字节），在能量、长度后（xx单位 冲突 位）\n            split[3] = split[3].Replace(\"字节\", \"B\").Replace(\"位\", \"b\").Replace(\"比特\", \"b\");\n\n            // Speed 速度    在长度、时间后（修补器 处理依赖），在数据后（节 冲突 字节）\n            split[3] = split[3].Replace(\"节\", \"kn\").Replace(\"mi每h\", \"mph\").Replace(\"mi/h\", \"mph\");\n\n            // 通用    最后\n            if (split[3].Contains(\"平方\")) { split[3] = split[3].Replace(\"平方\", string.Empty) + \"²\"; }\n            if (split[3].Contains(\"二次方\")) { split[3] = split[3].Replace(\"二次方\", string.Empty) + \"²\"; }\n            if (split[3].Contains(\"立方\")) { split[3] = split[3].Replace(\"立方\", string.Empty) + \"³\"; }\n            if (split[3].Contains(\"三次方\")) { split[3] = split[3].Replace(\"三次方\", string.Empty) + \"³\"; }\n            if (split[3].Contains('方')) { split[3] = split[3].Replace(\"方\", string.Empty) + \"²\"; }\n            split[3] = split[3].Replace(\"艾\", \"E\").Replace(\"拍\", \"P\").Replace(\"太\", \"T\").Replace(\"吉\", \"G\").Replace(\"兆\", \"M\").Replace(\"千\", \"k\").Replace(\"百\", \"h\").Replace(\"分\", \"d\").Replace(\"厘\", \"c\").Replace(\"毫\", \"m\").Replace(\"微\", \"μ\").Replace(\"纳\", \"n\");\n            split[3] = split[3].Replace(\"的\", string.Empty).Replace(\"个\", string.Empty).Replace(\"每\", \"/\");\n\n            // [For Debug]\n\n            // using System.Windows;\n            // System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo(\"msg.exe\");\n            // info.Arguments = \"LittleFox /time:1 \" + split[1] + \" -> \" + split[3];\n            // info.CreateNoWindow = true;\n            // System.Diagnostics.Process proc;\n            // proc = System.Diagnostics.Process.Start(info);\n        }\n#pragma warning restore SA1501 // Statement should not be on a single line\n\n        /// <summary>\n        /// Converts spelling \"kph\" to \"km/h\"\n        /// </summary>\n        public static void KPHHandler(ref string[] split)\n        {\n            split[1] = split[1].Replace(\"cph\", \"cm/h\", System.StringComparison.CurrentCultureIgnoreCase);\n            split[1] = split[1].Replace(\"kph\", \"km/h\", System.StringComparison.CurrentCultureIgnoreCase);\n            split[1] = split[1].Replace(\"kmph\", \"km/h\", System.StringComparison.CurrentCultureIgnoreCase);\n            split[1] = split[1].Replace(\"cmph\", \"cm/h\", System.StringComparison.CurrentCultureIgnoreCase);\n\n            split[3] = split[3].Replace(\"cph\", \"cm/h\", System.StringComparison.CurrentCultureIgnoreCase);\n            split[3] = split[3].Replace(\"kph\", \"km/h\", System.StringComparison.CurrentCultureIgnoreCase);\n            split[3] = split[3].Replace(\"kmph\", \"km/h\", System.StringComparison.CurrentCultureIgnoreCase);\n            split[3] = split[3].Replace(\"cmph\", \"cm/h\", System.StringComparison.CurrentCultureIgnoreCase);\n        }\n\n        /// <summary>\n        /// Converts spelling \"metre\" to \"meter\", also for centimetre and other variants\n        /// </summary>\n        public static void MetreToMeter(ref string[] split)\n        {\n            split[1] = split[1].Replace(\"metre\", \"meter\", System.StringComparison.CurrentCultureIgnoreCase);\n            split[3] = split[3].Replace(\"metre\", \"meter\", System.StringComparison.CurrentCultureIgnoreCase);\n        }\n\n        /// <summary>\n        /// Choose \"UsGallon\" or \"ImperialGallon\" according to current culture when the input contains \"gal\" or \"gallon\".\n        /// </summary>\n        public static void GallonHandler(ref string[] split, CultureInfo culture)\n        {\n            HashSet<string> britishCultureNames = new HashSet<string>() { \"en-AI\", \"en-VG\", \"en-GB\", \"en-KY\", \"en-MS\", \"en-AG\", \"en-DM\", \"en-GD\", \"en-KN\", \"en-LC\", \"en-VC\", \"en-IE\", \"en-GY\", \"en-AE\" };\n            if (string.Equals(split[1], \"gal\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[1], \"gallon\", StringComparison.OrdinalIgnoreCase))\n            {\n                if (britishCultureNames.Contains(culture.Name))\n                {\n                    split[1] = \"ImperialGallon\";\n                }\n                else\n                {\n                    split[1] = \"UsGallon\";\n                }\n            }\n\n            if (string.Equals(split[3], \"gal\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[3], \"gallon\", StringComparison.OrdinalIgnoreCase))\n            {\n                if (britishCultureNames.Contains(culture.Name))\n                {\n                    split[3] = \"ImperialGallon\";\n                }\n                else\n                {\n                    split[3] = \"UsGallon\";\n                }\n            }\n        }\n\n        /// <summary>\n        /// Choose \"UsOunce\" or \"ImperialOunce\" according to current culture when the input contains \"o.z\", \"o.z.\", \"oz\" or \"ounce\".\n        /// </summary>\n        public static void OunceHandler(ref string[] split, CultureInfo culture)\n        {\n            HashSet<string> britishCultureNames = new HashSet<string>() { \"en-AI\", \"en-VG\", \"en-GB\", \"en-KY\", \"en-MS\", \"en-AG\", \"en-DM\", \"en-GD\", \"en-KN\", \"en-LC\", \"en-VC\", \"en-IE\", \"en-GY\", \"en-AE\" };\n            if (string.Equals(split[1], \"o.z\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[1], \"ounce\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[1], \"o.z.\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[1], \"oz\", StringComparison.OrdinalIgnoreCase))\n            {\n                if (britishCultureNames.Contains(culture.Name))\n                {\n                    split[1] = \"ImperialOunce\";\n                }\n                else\n                {\n                    split[1] = \"UsOunce\";\n                }\n            }\n\n            if (string.Equals(split[3], \"o.z\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[3], \"ounce\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[3], \"o.z.\", StringComparison.OrdinalIgnoreCase) ||\n                string.Equals(split[3], \"oz\", StringComparison.OrdinalIgnoreCase))\n            {\n                if (britishCultureNames.Contains(culture.Name))\n                {\n                    split[3] = \"ImperialOunce\";\n                }\n                else\n                {\n                    split[3] = \"UsOunce\";\n                }\n            }\n        }\n\n        public static ConvertModel Parse(Query query)\n        {\n            string[] split = query.Search.Split(' ');\n\n            InputInterpreter.ShorthandFeetInchHandler(ref split, CultureInfo.CurrentCulture);\n            InputInterpreter.InputSpaceInserter(ref split);\n\n            if (split.Length != 4)\n            {\n                // deny any other queries than:\n                // 10 ft in cm\n                // 10 ft to cm\n                return null;\n            }\n\n            InputInterpreter.DegreePrefixer(ref split);\n            InputInterpreter.MetreToMeter(ref split);\n            InputInterpreter.KPHHandler(ref split);\n            InputInterpreter.GallonHandler(ref split, CultureInfo.CurrentCulture);\n            InputInterpreter.OunceHandler(ref split, CultureInfo.CurrentCulture);\n            if (!double.TryParse(split[0], out double value))\n            {\n                return null;\n            }\n\n            return new ConvertModel()\n            {\n                Value = value,\n                FromUnit = split[1],\n                ToUnit = split[3],\n            };\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Main.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading;\nusing System.Windows;\nusing System.Windows.Input;\n\nusing ManagedCommon;\nusing Wox.Plugin;\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.UnitConverter\n{\n    public class Main : IPlugin, IPluginI18n, IContextMenu, IDisposable\n    {\n        public string Name => Properties.Resources.plugin_name;\n\n        public string Description => Properties.Resources.plugin_description;\n\n        public static string PluginID => \"aa0ee9daff654fb7be452c2d77c471b9\";\n\n        private PluginInitContext _context;\n        private static string _icon_path;\n        private bool _disposed;\n\n        private static readonly CompositeFormat CopyToClipboard = System.Text.CompositeFormat.Parse(Properties.Resources.copy_to_clipboard);\n\n        public void Init(PluginInitContext context)\n        {\n            ArgumentNullException.ThrowIfNull(context);\n\n            _context = context;\n            _context.API.ThemeChanged += OnThemeChanged;\n            UpdateIconPath(_context.API.GetCurrentTheme());\n        }\n\n        public List<Result> Query(Query query)\n        {\n            ArgumentNullException.ThrowIfNull(query);\n\n            // Parse\n            ConvertModel convertModel = InputInterpreter.Parse(query);\n            if (convertModel == null)\n            {\n                return new List<Result>();\n            }\n\n            return UnitHandler.Convert(convertModel)\n                .Select(x => GetResult(x))\n                .ToList();\n        }\n\n        [System.Diagnostics.CodeAnalysis.SuppressMessage(\"StyleCop.CSharp.LayoutRules\", \"SA1501:Statement should not be on a single line\", Justification = \"<挂起>\")]\n        private Result GetResult(UnitConversionResult result)\n        {\n            string hack = $\"{result.QuantityInfo.Name}\";\n            if (hack == \"Acceleration\") { hack = \"加速度\"; }\n            else if (hack == \"Angle\") { hack = \"角度\"; }\n            else if (hack == \"Area\") { hack = \"面积\"; }\n            else if (hack == \"Duration\") { hack = \"时间\"; }\n            else if (hack == \"Energy\") { hack = \"能量\"; }\n            else if (hack == \"Information\") { hack = \"数据\"; }\n            else if (hack == \"Length\") { hack = \"长度\"; }\n            else if (hack == \"Mass\") { hack = \"质量\"; }\n            else if (hack == \"Power\") { hack = \"功率\"; }\n            else if (hack == \"Pressure\") { hack = \"压强\"; }\n            else if (hack == \"Speed\") { hack = \"速度\"; }\n            else if (hack == \"Temperature\") { hack = \"温度\"; }\n            else if (hack == \"Volume\") { hack = \"体积\"; }\n            return new Result\n            {\n                ContextData = result,\n                Title = result.ToString(null),\n                IcoPath = _icon_path,\n                Score = 300,\n                SubTitle = string.Format(CultureInfo.CurrentCulture, CopyToClipboard, result.QuantityInfo.Name),\n                Action = c =>\n                {\n                    var ret = false;\n                    var thread = new Thread(() =>\n                    {\n                        try\n                        {\n                            Clipboard.SetText(result.ConvertedValue.ToString(UnitConversionResult.CopyFormat, CultureInfo.CurrentCulture));\n                            ret = true;\n                        }\n                        catch (ExternalException ex)\n                        {\n                            Log.Exception(\"Copy failed\", ex, GetType());\n                            MessageBox.Show(ex.Message, Properties.Resources.copy_failed);\n                        }\n                    });\n                    thread.SetApartmentState(ApartmentState.STA);\n                    thread.Start();\n                    thread.Join();\n                    return ret;\n                },\n            };\n        }\n\n        private ContextMenuResult CreateContextMenuEntry(UnitConversionResult result)\n        {\n            return new ContextMenuResult\n            {\n                PluginName = Name,\n                Title = Properties.Resources.context_menu_copy,\n                Glyph = \"\\xE8C8\",\n                FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                AcceleratorKey = Key.Enter,\n                Action = _ =>\n                {\n                    bool ret = false;\n                    var thread = new Thread(() =>\n                    {\n                        try\n                        {\n                            Clipboard.SetText(result.ConvertedValue.ToString(UnitConversionResult.CopyFormat, CultureInfo.CurrentCulture));\n                            ret = true;\n                        }\n                        catch (ExternalException ex)\n                        {\n                            Log.Exception(\"Copy failed\", ex, GetType());\n                            MessageBox.Show(ex.Message, Properties.Resources.copy_failed);\n                        }\n                    });\n                    thread.SetApartmentState(ApartmentState.STA);\n                    thread.Start();\n                    thread.Join();\n                    return ret;\n                },\n            };\n        }\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            if (!(selectedResult?.ContextData is UnitConversionResult))\n            {\n                return new List<ContextMenuResult>();\n            }\n\n            List<ContextMenuResult> contextResults = new List<ContextMenuResult>();\n            UnitConversionResult result = selectedResult.ContextData as UnitConversionResult;\n            contextResults.Add(CreateContextMenuEntry(result));\n\n            return contextResults;\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Properties.Resources.plugin_name;\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Properties.Resources.plugin_description;\n        }\n\n        private void OnThemeChanged(Theme currentTheme, Theme newTheme)\n        {\n            UpdateIconPath(newTheme);\n        }\n\n        private static void UpdateIconPath(Theme theme)\n        {\n            if (theme == Theme.Light || theme == Theme.HighContrastWhite)\n            {\n                _icon_path = \"Images/unitconverter.light.png\";\n            }\n            else\n            {\n                _icon_path = \"Images/unitconverter.dark.png\";\n            }\n        }\n\n        public void Dispose()\n        {\n            Dispose(disposing: true);\n            GC.SuppressFinalize(this);\n        }\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (!_disposed)\n            {\n                if (disposing)\n                {\n                    if (_context != null && _context.API != null)\n                    {\n                        _context.API.ThemeChanged -= OnThemeChanged;\n                    }\n\n                    _disposed = true;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.UnitConverter/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"context_menu_copy\" xml:space=\"preserve\">\n    <value>复制 (回车)</value>\n  </data>\n  <data name=\"copy_failed\" xml:space=\"preserve\">\n    <value>复制失败</value>\n  </data>\n  <data name=\"copy_to_clipboard\" xml:space=\"preserve\">\n    <value>复制转换结果 ({0})</value>\n  </data>\n  <data name=\"plugin_description\" xml:space=\"preserve\">\n    <value>进行单位转换（例如 10厘米 -&gt; 米）</value>\n  </data>\n  <data name=\"plugin_name\" xml:space=\"preserve\">\n    <value>单位转换</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Main.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Windows;\nusing System.Windows.Input;\n\nusing Community.PowerToys.Run.Plugin.VSCodeWorkspaces.Properties;\nusing Community.PowerToys.Run.Plugin.VSCodeWorkspaces.RemoteMachinesHelper;\nusing Community.PowerToys.Run.Plugin.VSCodeWorkspaces.VSCodeHelper;\nusing Community.PowerToys.Run.Plugin.VSCodeWorkspaces.WorkspacesHelper;\n\nusing Wox.Infrastructure;\nusing Wox.Plugin;\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.VSCodeWorkspaces\n{\n    public class Main : IPlugin, IPluginI18n, IContextMenu\n    {\n        private PluginInitContext _context;\n\n        public string Name => GetTranslatedPluginTitle();\n\n        public string Description => GetTranslatedPluginDescription();\n\n        public static string PluginID => \"525995402BEF4A8CA860D92F6D108092\";\n\n        public Main()\n        {\n            VSCodeInstances.LoadVSCodeInstances();\n        }\n\n        private readonly VSCodeWorkspacesApi _workspacesApi = new VSCodeWorkspacesApi();\n\n        private readonly VSCodeRemoteMachinesApi _machinesApi = new VSCodeRemoteMachinesApi();\n\n        public List<Result> Query(Query query)\n        {\n            var results = new List<Result>();\n\n            if (query != null)\n            {\n                // Search opened workspaces\n                _workspacesApi.Workspaces.ForEach(a =>\n                {\n                    var title = a.WorkspaceType == WorkspaceType.ProjectFolder ? a.FolderName : a.FolderName.Replace(\".code-workspace\", $\" ({Resources.Workspace})\");\n\n                    var typeWorkspace = a.WorkspaceEnvironmentToString();\n                    if (a.WorkspaceEnvironment != WorkspaceEnvironment.Local)\n                    {\n                        title = $\"{title}{(a.ExtraInfo != null ? $\" - {a.ExtraInfo}\" : string.Empty)} ({typeWorkspace})\";\n                    }\n\n                    var tooltip = new ToolTipData(title, $\"{(a.WorkspaceType == WorkspaceType.WorkspaceFile ? Resources.Workspace : Resources.ProjectFolder)}{(a.WorkspaceEnvironment != WorkspaceEnvironment.Local ? $\" {Resources.In} {typeWorkspace}\" : string.Empty)}: {SystemPath.RealPath(a.RelativePath)}\");\n\n                    results.Add(new Result\n                    {\n                        Title = title,\n                        SubTitle = $\"{(a.WorkspaceType == WorkspaceType.WorkspaceFile ? Resources.Workspace : Resources.ProjectFolder)}{(a.WorkspaceEnvironment != WorkspaceEnvironment.Local ? $\" {Resources.In} {typeWorkspace}\" : string.Empty)}: {SystemPath.RealPath(a.RelativePath)}\",\n                        Icon = a.VSCodeInstance.WorkspaceIcon,\n                        ToolTipData = tooltip,\n                        Action = c =>\n                        {\n                            bool hide;\n                            try\n                            {\n                                var process = new ProcessStartInfo\n                                {\n                                    FileName = a.VSCodeInstance.ExecutablePath,\n                                    UseShellExecute = true,\n                                    Arguments = a.WorkspaceType == WorkspaceType.ProjectFolder ? $\"--folder-uri {a.Path}\" : $\"--file-uri {a.Path}\",\n                                    WindowStyle = ProcessWindowStyle.Hidden,\n                                };\n                                Process.Start(process);\n\n                                hide = true;\n                            }\n                            catch (Win32Exception ex)\n                            {\n                                HandleError(\"无法打开此文件\", ex, showMsg: true);\n                                hide = false;\n                            }\n\n                            return hide;\n                        },\n                        ContextData = a,\n                    });\n                });\n\n                // Search opened remote machines\n                _machinesApi.Machines.ForEach(a =>\n                {\n                    var title = $\"{a.Host}\";\n\n                    if (a.User != null && a.User != string.Empty && a.HostName != null && a.HostName != string.Empty)\n                    {\n                        title += $\" [{a.User}@{a.HostName}]\";\n                    }\n\n                    var tooltip = new ToolTipData(title, Resources.SSHRemoteMachine);\n\n                    results.Add(new Result\n                    {\n                        Title = title,\n                        SubTitle = Resources.SSHRemoteMachine,\n                        Icon = a.VSCodeInstance.RemoteIcon,\n                        ToolTipData = tooltip,\n                        Action = c =>\n                        {\n                            bool hide;\n                            try\n                            {\n                                var process = new ProcessStartInfo()\n                                {\n                                    FileName = a.VSCodeInstance.ExecutablePath,\n                                    UseShellExecute = true,\n                                    Arguments = $\"--new-window --enable-proposed-api ms-vscode-remote.remote-ssh --remote ssh-remote+{((char)34) + a.Host + ((char)34)}\",\n                                    WindowStyle = ProcessWindowStyle.Hidden,\n                                };\n                                Process.Start(process);\n\n                                hide = true;\n                            }\n                            catch (Win32Exception ex)\n                            {\n                                HandleError(\"无法打开此文件\", ex, showMsg: true);\n                                hide = false;\n                            }\n\n                            return hide;\n                        },\n                        ContextData = a,\n                    });\n                });\n            }\n\n            results = results.Where(a => a.Title.Contains(query.Search, StringComparison.InvariantCultureIgnoreCase)).ToList();\n\n            results.ForEach(x =>\n            {\n                if (x.Score == 0)\n                {\n                    x.Score = 100;\n                }\n\n                // intersect the title with the query\n                var intersection = Convert.ToInt32(x.Title.ToLowerInvariant().Intersect(query.Search.ToLowerInvariant()).Count() * query.Search.Length);\n                var differenceWithQuery = Convert.ToInt32((x.Title.Length - intersection) * query.Search.Length * 0.7);\n                x.Score = x.Score - differenceWithQuery + intersection;\n\n                // if is a remote machine give it 12 extra points\n                if (x.ContextData is VSCodeRemoteMachine)\n                {\n                    x.Score = Convert.ToInt32(x.Score + (intersection * 2));\n                }\n            });\n\n            results = results.OrderByDescending(x => x.Score).ToList();\n            if (query.Search == string.Empty || query.Search.Replace(\" \", string.Empty) == string.Empty)\n            {\n                results = results.OrderBy(x => x.Title).ToList();\n            }\n\n            return results;\n        }\n\n        public void Init(PluginInitContext context)\n        {\n            _context = context;\n        }\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            if (selectedResult?.ContextData is not VSCodeWorkspace workspace)\n            {\n                return new List<ContextMenuResult>();\n            }\n\n            string realPath = SystemPath.RealPath(workspace.RelativePath);\n\n            return new List<ContextMenuResult>\n            {\n                new ContextMenuResult\n                {\n                    PluginName = Name,\n                    Title = $\"{Resources.CopyPath} (Ctrl+C)\",\n                    Glyph = \"\\xE8C8\", // Copy\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    AcceleratorKey = Key.C,\n                    AcceleratorModifiers = ModifierKeys.Control,\n                    Action = context => CopyToClipboard(realPath),\n                },\n                new ContextMenuResult\n                {\n                    PluginName = Name,\n                    Title = $\"{Resources.OpenInExplorer} (Ctrl+Shift+F)\",\n                    Glyph = \"\\xEC50\", // File Explorer\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    AcceleratorKey = Key.F,\n                    AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                    Action = context => OpenInExplorer(realPath),\n                },\n                new ContextMenuResult\n                {\n                    PluginName = Name,\n                    Title = $\"{Resources.OpenInConsole} (Ctrl+Shift+C)\",\n                    Glyph = \"\\xE756\", // Command Prompt\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    AcceleratorKey = Key.C,\n                    AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                    Action = context => OpenInConsole(realPath),\n                },\n            };\n        }\n\n        private bool CopyToClipboard(string path)\n        {\n            try\n            {\n                Clipboard.SetText(path);\n                return true;\n            }\n            catch (Exception ex)\n            {\n                HandleError(\"复制失败\", ex, showMsg: true);\n                return false;\n            }\n        }\n\n        private bool OpenInConsole(string path)\n        {\n            try\n            {\n                Helper.OpenInConsole(path);\n                return true;\n            }\n            catch (Exception ex)\n            {\n                HandleError($\"无法在终端打开此路径: {path}\", ex, showMsg: true);\n                return false;\n            }\n        }\n\n        private bool OpenInExplorer(string path)\n        {\n            if (!Helper.OpenInShell(\"explorer.exe\", $\"\\\"{path}\\\"\"))\n            {\n                HandleError($\"无法在文件管理器打开此路径: {path}\", showMsg: true);\n                return false;\n            }\n\n            return true;\n        }\n\n        private void HandleError(string msg, Exception exception = null, bool showMsg = false)\n        {\n            if (exception != null)\n            {\n                Log.Exception(msg, exception, exception.GetType());\n            }\n            else\n            {\n                Log.Error(msg, typeof(VSCodeWorkspaces.Main));\n            }\n\n            if (showMsg)\n            {\n                _context.API.ShowMsg(\n                    $\"插件: {_context.CurrentPluginMetadata.Name}\",\n                    msg);\n            }\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Resources.PluginTitle;\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Resources.PluginDescription;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.VSCodeWorkspaces/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"PluginTitle\" xml:space=\"preserve\">\n    <value>VS Code 工作区</value>\n  </data>\n  <data name=\"In\" xml:space=\"preserve\">\n    <value>位于</value>\n    <comment>Used to indicate the location where something is</comment>\n  </data>\n  <data name=\"PluginDescription\" xml:space=\"preserve\">\n    <value>打开 VS Code 的常用工作区、远程计算机（SSH、Codespaces）和容器，VS Code 路径须在 PATH 环境变量中</value>\n    <comment>VS Code is the name of a product. PATH is the name of an environment variable. Don't translate it.</comment>\n  </data>\n  <data name=\"SSHRemoteMachine\" xml:space=\"preserve\">\n    <value>SSH 远程机</value>\n  </data>\n  <data name=\"TypeWorkspaceContainer\" xml:space=\"preserve\">\n    <value>容器</value>\n    <comment>As in \"Visual Studio Code workspace container type</comment>\n  </data>\n  <data name=\"TypeWorkspaceLocal\" xml:space=\"preserve\">\n    <value>本地</value>\n    <comment>As in \"The workspace is on the local machine\"</comment>\n  </data>\n  <data name=\"Workspace\" xml:space=\"preserve\">\n    <value>工作区</value>\n    <comment>It refers to the Visual Studio Code .code-workspace</comment>\n  </data>\n  <data name=\"TypeWorkspaceDevContainer\" xml:space=\"preserve\">\n    <value>开发容器</value>\n    <comment>As in \"Visual Studio Code Dev Container workspace \"</comment>\n  </data>\n  <data name=\"ProjectFolder\" xml:space=\"preserve\">\n    <value>项目文件夹</value>\n    <comment>It refers to the Visual Studio Code Project Folders</comment>\n  </data>\n  <data name=\"CopyPath\" xml:space=\"preserve\">\n    <value>复制路径</value>\n  </data>\n  <data name=\"OpenInConsole\" xml:space=\"preserve\">\n    <value>打开终端</value>\n  </data>\n  <data name=\"OpenInExplorer\" xml:space=\"preserve\">\n    <value>打开路径</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Base64/Base64DecodeRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Text;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Base64\n{\n    public class Base64DecodeRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"Base64 解码结果\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private string DataToDecode { get; set; }\n\n        public Base64DecodeRequest(string dataToDecode)\n        {\n            DataToDecode = dataToDecode ?? throw new ArgumentNullException(nameof(dataToDecode));\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                Result = System.Convert.FromBase64String(DataToDecode);\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            if (Result != null)\n            {\n                return Encoding.UTF8.GetString(Result);\n            }\n            else\n            {\n                return string.Empty;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Base64/Base64Request.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Text;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Base64\n{\n    public class Base64Request : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"Base64 编码结果\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private byte[] DataToEncode { get; set; }\n\n        public Base64Request(byte[] dataToEncode)\n        {\n            DataToEncode = dataToEncode ?? throw new ArgumentNullException(nameof(dataToEncode));\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                Result = Encoding.UTF8.GetBytes(System.Convert.ToBase64String(DataToEncode));\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            return Encoding.UTF8.GetString(Result);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/GUID/GUIDRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Security.Cryptography;\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.GUID\n{\n    public class GUIDRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private int Version { get; set; }\n\n        public string Description => Version switch\n        {\n            1 => \"UUID v1：基于当前时间和网卡 MAC 地址\",\n            3 => $\"UUID v3：基于给定名称进行 {HashAlgorithmName.MD5} 散列计算\",\n            4 => \"UUID v4：随机数值\",\n            5 => $\"UUID v5：基于给定名称进行 {HashAlgorithmName.SHA1} 散列计算\",\n            7 => \"UUID v7：当前时间+随机数值\",\n            _ => string.Empty,\n        };\n\n        private Guid? GuidNamespace { get; set; }\n\n        private string GuidName { get; set; }\n\n        private Guid GuidResult { get; set; }\n\n        private static readonly string NullNamespaceError = $\"第一个参数需要是一个 UUID 或者是以下选项之一：{string.Join(\"、\", GUIDGenerator.PredefinedNamespaces.Keys)}\";\n\n        public GUIDRequest(int version, string guidNamespace = null, string name = null)\n        {\n            Version = version;\n\n            if (Version is < 1 or > 7 or 2 or 6)\n            {\n                throw new ArgumentException(\"不支持此 GUID 版本，目前仅支持版本 1、3、4、5、7\");\n            }\n\n            if (version is 3 or 5)\n            {\n                if (guidNamespace == null)\n                {\n                    throw new ArgumentNullException(null, NullNamespaceError);\n                }\n\n                if (GUIDGenerator.PredefinedNamespaces.TryGetValue(guidNamespace.ToLowerInvariant(), out Guid guid))\n                {\n                    GuidNamespace = guid;\n                }\n                else if (Guid.TryParse(guidNamespace, out guid))\n                {\n                    GuidNamespace = guid;\n                }\n                else\n                {\n                    throw new ArgumentNullException(null, NullNamespaceError);\n                }\n\n                if (name == null)\n                {\n                    throw new ArgumentNullException(nameof(name));\n                }\n                else\n                {\n                    GuidName = name;\n                }\n            }\n            else\n            {\n                GuidNamespace = null;\n            }\n\n            ErrorMessage = null;\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                Guid guid = Version switch\n                {\n                    1 => GUIDGenerator.V1(),\n                    3 => GUIDGenerator.V3(GuidNamespace.Value, GuidName),\n                    4 => GUIDGenerator.V4(),\n                    5 => GUIDGenerator.V5(GuidNamespace.Value, GuidName),\n                    7 => GUIDGenerator.V7(),\n                    _ => default,\n                };\n                if (guid != default)\n                {\n                    GuidResult = guid;\n                }\n\n                Result = GuidResult.ToByteArray();\n            }\n            catch (InvalidOperationException e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            if (!IsSuccessful)\n            {\n                return ErrorMessage;\n            }\n\n            return GuidResult.ToString();\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/DataEscapeRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Text;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri\n{\n    public class DataEscapeRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"百分比编码后的数据\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private string DataToEscape { get; set; }\n\n        public DataEscapeRequest(string dataToEscape)\n        {\n            DataToEscape = dataToEscape ?? throw new ArgumentNullException(nameof(dataToEscape));\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                Result = Encoding.UTF8.GetBytes(System.Uri.EscapeDataString(DataToEscape));\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            return Encoding.UTF8.GetString(Result);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/DataUnescapeRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Text;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri\n{\n    public class DataUnescapeRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"百分比解码后的数据\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private string DataToUnescape { get; set; }\n\n        public DataUnescapeRequest(string dataToUnescape)\n        {\n            DataToUnescape = dataToUnescape ?? throw new ArgumentNullException(nameof(dataToUnescape));\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                Result = Encoding.UTF8.GetBytes(System.Uri.UnescapeDataString(DataToUnescape));\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            if (Result != null)\n            {\n                return Encoding.UTF8.GetString(Result);\n            }\n            else\n            {\n                return string.Empty;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/HexEscapeRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Linq;\nusing System.Text;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri\n{\n    public class HexEscapeRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"百分比编码后的字符\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private string DataToEscape { get; set; }\n\n        public HexEscapeRequest(string dataToEscape)\n        {\n            DataToEscape = dataToEscape ?? throw new ArgumentNullException(nameof(dataToEscape));\n\n            // Validate that we have only one character\n            if (dataToEscape.Length != 1)\n            {\n                throw new ArgumentOutOfRangeException(nameof(dataToEscape));\n            }\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                char charToEscape = DataToEscape[0];\n                Result = Encoding.UTF8.GetBytes(System.Uri.HexEscape(charToEscape));\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            return Encoding.UTF8.GetString(Result);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/HexUnescapeRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Text;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri\n{\n    public class HexUnescapeRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"百分比解码后的字符\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private string DataToUnescape { get; set; }\n\n        public HexUnescapeRequest(string dataToUnescape)\n        {\n            DataToUnescape = dataToUnescape ?? throw new ArgumentNullException(nameof(dataToUnescape));\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                int index = 0;\n                if (System.Uri.IsHexEncoding(DataToUnescape, index))\n                {\n                    Result = Encoding.UTF8.GetBytes(System.Uri.HexUnescape(DataToUnescape, ref index).ToString());\n                }\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            if (Result != null)\n            {\n                return Encoding.UTF8.GetString(Result);\n            }\n            else\n            {\n                return string.Empty;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/UrlDecodeRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Diagnostics;\nusing System.Security.Policy;\nusing System.Text;\nusing System.Web;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri\n{\n    public class UrlDecodeRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"URL 解码结果\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private string DataToDecode { get; set; }\n\n        public UrlDecodeRequest(string dataToDecode)\n        {\n            DataToDecode = dataToDecode ?? throw new ArgumentNullException(nameof(dataToDecode));\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                Result = Encoding.UTF8.GetBytes(HttpUtility.UrlDecode(DataToDecode));\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            if (Result != null)\n            {\n                return Encoding.UTF8.GetString(Result);\n            }\n            else\n            {\n                return string.Empty;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Generators/Uri/UrlEncodeRequest.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Security.Policy;\nusing System.Text;\nusing System.Web;\n\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator.Uri\n{\n    public class UrlEncodeRequest : IComputeRequest\n    {\n        public byte[] Result { get; set; }\n\n        public string Description => \"URL 编码结果\";\n\n        public bool IsSuccessful { get; set; }\n\n        public string ErrorMessage { get; set; }\n\n        private string DataToEncode { get; set; }\n\n        public UrlEncodeRequest(string dataToEncode)\n        {\n            DataToEncode = dataToEncode ?? throw new ArgumentNullException(nameof(dataToEncode));\n        }\n\n        public bool Compute()\n        {\n            IsSuccessful = true;\n            try\n            {\n                Result = Encoding.UTF8.GetBytes(HttpUtility.UrlEncode(DataToEncode));\n            }\n            catch (Exception e)\n            {\n                Log.Exception(e.Message, e, GetType());\n                ErrorMessage = e.Message;\n                IsSuccessful = false;\n            }\n\n            return IsSuccessful;\n        }\n\n        public string ResultToString()\n        {\n            return Encoding.UTF8.GetString(Result);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/InputParser.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Security.Cryptography;\nusing System.Text;\n\nusing Community.PowerToys.Run.Plugin.ValueGenerator.Base64;\nusing Community.PowerToys.Run.Plugin.ValueGenerator.GUID;\nusing Community.PowerToys.Run.Plugin.ValueGenerator.Hashing;\nusing Community.PowerToys.Run.Plugin.ValueGenerator.Uri;\nusing Wox.Plugin;\nusing Wox.Plugin.Logger;\n\nnamespace Community.PowerToys.Run.Plugin.ValueGenerator\n{\n    public class InputParser\n    {\n        public IComputeRequest ParseInput(Query query)\n        {\n            IComputeRequest request;\n\n            if (query.Terms.Count == 0)\n            {\n                throw new FormatException(\"Empty request\");\n            }\n\n            string command = query.Terms[0];\n\n            if (command.Equals(\"md5\", StringComparison.OrdinalIgnoreCase))\n            {\n                int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n\n                if (content == string.Empty)\n                {\n                    throw new FormatException(\"Empty hash request\");\n                }\n\n                Log.Debug($\"Will calculate MD5 hash for: {content}\", GetType());\n                request = new HashRequest(HashAlgorithmName.MD5, Encoding.UTF8.GetBytes(content));\n            }\n            else if (command.StartsWith(\"sha\", StringComparison.InvariantCultureIgnoreCase))\n            {\n                int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                HashAlgorithmName algorithmName;\n\n                switch (command.Substring(3))\n                {\n                    case \"1\":\n                        algorithmName = HashAlgorithmName.SHA1;\n                        break;\n\n                    case \"256\":\n                        algorithmName = HashAlgorithmName.SHA256;\n                        break;\n\n                    case \"384\":\n                        algorithmName = HashAlgorithmName.SHA384;\n                        break;\n\n                    case \"512\":\n                        algorithmName = HashAlgorithmName.SHA512;\n                        break;\n                    default:\n                        throw new FormatException(\"Unknown SHA variant. Supported variants: SHA1, SHA256, SHA384, SHA512\");\n                }\n\n                if (content == string.Empty)\n                {\n                    throw new FormatException(\"Empty hash request\");\n                }\n\n                Log.Debug($\"Will calculate {algorithmName} hash for: {content}\", GetType());\n                request = new HashRequest(algorithmName, Encoding.UTF8.GetBytes(content));\n            }\n            else if (command.StartsWith(\"guid\", StringComparison.InvariantCultureIgnoreCase) ||\n                     command.StartsWith(\"uuid\", StringComparison.InvariantCultureIgnoreCase))\n            {\n                string content = query.Search.Substring(command.Length).Trim();\n\n                // Default to version 4\n                int version = 4;\n                string versionQuery = command.Substring(4);\n\n                if (versionQuery.Length > 0)\n                {\n                    if (versionQuery.StartsWith(\"v\", StringComparison.InvariantCultureIgnoreCase))\n                    {\n                        versionQuery = versionQuery.Substring(1);\n                    }\n\n                    if (!int.TryParse(versionQuery, null, out version))\n                    {\n                        throw new FormatException(\"Could not determine requested GUID version. Supported versions are 1, 3, 4, 5, and 7\");\n                    }\n                }\n\n                if (version == 3 || version == 5)\n                {\n                    string[] sParameters = content.Split(\" \");\n\n                    if (sParameters.Length != 2)\n                    {\n                        throw new ArgumentException($\"UUID v{version} 请输入两个参数：一个命名空间（固定选项或 UUID）和一个名称。\\n例如：uuidv{version} ns:<DNS, URL, OID, 或 X500> <填入名称>\");\n                    }\n\n                    string namespaceParameter = sParameters[0];\n                    string nameParameter = sParameters[1];\n\n                    request = new GUIDRequest(version, namespaceParameter, nameParameter);\n                }\n                else\n                {\n                    request = new GUIDRequest(version);\n                }\n            }\n            else if (command.Equals(\"base64\", StringComparison.OrdinalIgnoreCase))\n            {\n                int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                request = new Base64Request(Encoding.UTF8.GetBytes(content));\n            }\n            else if (command.Equals(\"base64d\", StringComparison.OrdinalIgnoreCase))\n            {\n                int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                request = new Base64DecodeRequest(content);\n            }\n            else if (command.StartsWith(\"esc:\", StringComparison.OrdinalIgnoreCase))\n            {\n                // Escape things\n                if (command.Equals(\"esc:data\", StringComparison.OrdinalIgnoreCase))\n                {\n                    int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                    string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                    request = new DataEscapeRequest(content);\n                }\n                else if (command.Equals(\"esc:hex\", StringComparison.OrdinalIgnoreCase))\n                {\n                    int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                    string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n\n                    // This is only for single chars\n                    if (content.Length > 1)\n                    {\n                        throw new ArgumentException($\"无效查询: {query.RawUserQuery}，字符数量过多\");\n                    }\n                    else if (content.Length == 0)\n                    {\n                        throw new FormatException($\"Invalid Query: {query.RawUserQuery}\");\n                    }\n\n                    request = new HexEscapeRequest(content);\n                }\n                else\n                {\n                    throw new FormatException($\"Invalid Query: {query.RawUserQuery}\");\n                }\n            }\n            else if (command.StartsWith(\"uesc:\", StringComparison.OrdinalIgnoreCase))\n            {\n                // Unescape things\n                if (command.Equals(\"uesc:data\", StringComparison.OrdinalIgnoreCase))\n                {\n                    int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                    string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                    request = new DataUnescapeRequest(content);\n                }\n                else if (command.Equals(\"uesc:hex\", StringComparison.OrdinalIgnoreCase))\n                {\n                    int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                    string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                    request = new HexUnescapeRequest(content);\n                }\n                else\n                {\n                    throw new FormatException($\"Invalid Query: {query.RawUserQuery}\");\n                }\n            }\n            else if (command.Equals(\"url\", StringComparison.OrdinalIgnoreCase))\n            {\n                int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                request = new UrlEncodeRequest(content);\n            }\n            else if (command.Equals(\"urld\", StringComparison.OrdinalIgnoreCase))\n            {\n                int commandIndex = query.RawUserQuery.IndexOf(command, StringComparison.InvariantCultureIgnoreCase);\n                string content = query.RawUserQuery.Substring(commandIndex + command.Length).Trim();\n                request = new UrlDecodeRequest(content);\n            }\n            else\n            {\n                throw new FormatException($\"Invalid Query: {query.RawUserQuery}\");\n            }\n\n            return request;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.ValueGenerator/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"copy_failed\" xml:space=\"preserve\">\n    <value>复制失败</value>\n  </data>\n  <data name=\"copy_to_clipboard\" xml:space=\"preserve\">\n    <value>复制 {0} 到剪贴板</value>\n  </data>\n  <data name=\"error_title\" xml:space=\"preserve\">\n    <value>编码生成器出错</value>\n  </data>\n  <data name=\"generator_description_base64\" xml:space=\"preserve\">\n    <value>Base64 编码</value>\n  </data>\n  <data name=\"generator_description_base64d\" xml:space=\"preserve\">\n    <value>Base64 解码</value>\n  </data>\n  <data name=\"generator_description_esc_data\" xml:space=\"preserve\">\n    <value>百分号编码</value>\n  </data>\n  <data name=\"generator_description_esc_hex\" xml:space=\"preserve\">\n    <value>百分号编码，单个十六进制字符</value>\n  </data>\n  <data name=\"generator_description_hash\" xml:space=\"preserve\">\n    <value>计算 {0} 散列值</value>\n  </data>\n  <data name=\"generator_description_uesc_data\" xml:space=\"preserve\">\n    <value>百分号解码</value>\n  </data>\n  <data name=\"generator_description_uesc_hex\" xml:space=\"preserve\">\n    <value>百分号解码，单个十六进制字符</value>\n  </data>\n  <data name=\"generator_description_url\" xml:space=\"preserve\">\n    <value>URL 编码</value>\n  </data>\n  <data name=\"generator_description_urld\" xml:space=\"preserve\">\n    <value>URL 解码</value>\n  </data>\n  <data name=\"generator_description_uuid\" xml:space=\"preserve\">\n    <value>生成随机 UUID</value>\n  </data>\n  <data name=\"generator_description_uuidv1\" xml:space=\"preserve\">\n    <value>生成 UUID 版本 1，基于时间</value>\n  </data>\n  <data name=\"generator_description_uuidv3\" xml:space=\"preserve\">\n    <value>生成 UUID 版本 3，基于给定名称进行 MD5 散列计算</value>\n  </data>\n  <data name=\"generator_description_uuidv4\" xml:space=\"preserve\">\n    <value>生成 UUID 版本 4，随机数值</value>\n  </data>\n  <data name=\"generator_description_uuidv5\" xml:space=\"preserve\">\n    <value>生成 UUID 版本 5，基于给定名称进行 SHA1 散列计算</value>\n  </data>\n  <data name=\"generator_description_uuidv7\" xml:space=\"preserve\">\n    <value>生成 UUID 版本 7，当前时间+随机数值</value>\n  </data>\n  <data name=\"generator_description_your_input\" xml:space=\"preserve\">\n    <value>输入内容</value>\n    <comment>Usage example: \"md5 &lt;your input&gt;\"</comment>\n  </data>\n  <data name=\"generator_example\" xml:space=\"preserve\">\n    <value>例如：{0}</value>\n    <comment>The arg following is the usage example</comment>\n  </data>\n  <data name=\"or\" xml:space=\"preserve\">\n    <value>或</value>\n    <comment>Used to indicate alternatives or options available</comment>\n  </data>\n  <data name=\"plugin_description\" xml:space=\"preserve\">\n    <value>生成特定编码和计算散列值</value>\n  </data>\n  <data name=\"plugin_name\" xml:space=\"preserve\">\n    <value>编码生成器</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.WebSearch/Main.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing System.Windows.Controls;\n\nusing ManagedCommon;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Wox.Infrastructure;\nusing Wox.Plugin;\nusing Wox.Plugin.Logger;\n\nusing BrowserInfo = Wox.Plugin.Common.DefaultBrowserInfo;\n\nnamespace Community.PowerToys.Run.Plugin.WebSearch\n{\n    public class Main : IPlugin, IPluginI18n, IContextMenu, ISettingProvider, IReloadable, IDisposable\n    {\n        // Should only be set in Init()\n        private Action onPluginError;\n\n        private const string NotGlobalIfUri = nameof(NotGlobalIfUri);\n\n        /// <summary>If true, dont show global result on queries that are URIs</summary>\n        private bool _notGlobalIfUri;\n\n        private PluginInitContext _context;\n\n        private string _iconPath;\n\n        private bool _disposed;\n\n        public string Name => Properties.Resources.plugin_name;\n\n        public string Description => Properties.Resources.plugin_description;\n\n        public static string PluginID => \"9F1B49201C3F4BF781CAAD5CD88EA4DC\";\n\n        private static readonly CompositeFormat PluginInBrowserName = System.Text.CompositeFormat.Parse(Properties.Resources.plugin_in_browser_name);\n        private static readonly CompositeFormat PluginOpen = System.Text.CompositeFormat.Parse(Properties.Resources.plugin_open);\n        private static readonly CompositeFormat PluginSearchFailed = System.Text.CompositeFormat.Parse(Properties.Resources.plugin_search_failed);\n\n        public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()\n        {\n            new PluginAdditionalOption()\n            {\n                Key = NotGlobalIfUri,\n                DisplayLabel = Properties.Resources.plugin_global_if_uri,\n                Value = false,\n            },\n        };\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            return new List<ContextMenuResult>(0);\n        }\n\n        public List<Result> Query(Query query)\n        {\n            ArgumentNullException.ThrowIfNull(query);\n\n            var results = new List<Result>();\n\n            // empty query\n            if (string.IsNullOrEmpty(query.Search))\n            {\n                string arguments = \"? \";\n                results.Add(new Result\n                {\n                    Title = Properties.Resources.plugin_description,\n                    SubTitle = string.Format(CultureInfo.CurrentCulture, PluginInBrowserName, BrowserInfo.Name ?? BrowserInfo.MSEdgeName),\n                    QueryTextDisplay = string.Empty,\n                    IcoPath = _iconPath,\n                    ProgramArguments = arguments,\n                    Action = action =>\n                    {\n                        if (!Helper.OpenCommandInShell(BrowserInfo.Path, BrowserInfo.ArgumentsPattern, arguments))\n                        {\n                            onPluginError();\n                            return false;\n                        }\n\n                        return true;\n                    },\n                });\n                return results;\n            }\n            else\n            {\n                string searchTerm = query.Search;\n\n                // Don't include in global results if the query is a URI (and if the option NotGlobalIfUri is enabled)\n                if (_notGlobalIfUri\n                    && AreResultsGlobal()\n                    && IsURI(searchTerm))\n                {\n                    return results;\n                }\n\n                var result = new Result\n                {\n                    Title = searchTerm,\n                    SubTitle = string.Format(CultureInfo.CurrentCulture, PluginOpen, BrowserInfo.Name ?? BrowserInfo.MSEdgeName),\n                    QueryTextDisplay = searchTerm,\n                    IcoPath = _iconPath,\n                };\n\n                string arguments = $\"? {searchTerm}\";\n\n                result.ProgramArguments = arguments;\n                result.Action = action =>\n                {\n                    if (!Helper.OpenCommandInShell(BrowserInfo.Path, BrowserInfo.ArgumentsPattern, arguments))\n                    {\n                        onPluginError();\n                        return false;\n                    }\n\n                    return true;\n                };\n\n                results.Add(result);\n            }\n\n            return results;\n\n            bool AreResultsGlobal()\n            {\n                return string.IsNullOrEmpty(query.ActionKeyword);\n            }\n\n            // Checks if input is a URI the same way Microsoft.Plugin.Uri.UriHelper.ExtendedUriParser does\n            bool IsURI(string input)\n            {\n                if (input.EndsWith(\":\", StringComparison.OrdinalIgnoreCase)\n                    && !input.StartsWith(\"http\", StringComparison.OrdinalIgnoreCase)\n                    && !input.Contains('/', StringComparison.OrdinalIgnoreCase)\n                    && !input.All(char.IsDigit)\n                    && System.Text.RegularExpressions.Regex.IsMatch(input, @\"^([a-z][a-z0-9+\\-.]*):\"))\n                {\n                    return true;\n                }\n\n                if (input.EndsWith(\":\", StringComparison.CurrentCulture)\n                    || input.EndsWith(\".\", StringComparison.CurrentCulture)\n                    || input.EndsWith(\":/\", StringComparison.CurrentCulture)\n                    || input.EndsWith(\"://\", StringComparison.CurrentCulture)\n                    || input.All(char.IsDigit))\n                {\n                    return false;\n                }\n\n                try\n                {\n                    _ = new UriBuilder(input);\n                }\n                catch (UriFormatException)\n                {\n                    return false;\n                }\n\n                return true;\n            }\n        }\n\n        public void Init(PluginInitContext context)\n        {\n            _context = context ?? throw new ArgumentNullException(nameof(context));\n            _context.API.ThemeChanged += OnThemeChanged;\n            UpdateIconPath(_context.API.GetCurrentTheme());\n            BrowserInfo.UpdateIfTimePassed();\n\n            onPluginError = () =>\n            {\n                string errorMsgString = string.Format(CultureInfo.CurrentCulture, PluginSearchFailed, BrowserInfo.Name ?? BrowserInfo.MSEdgeName);\n\n                Log.Error(errorMsgString, this.GetType());\n                _context.API.ShowMsg(\n                    $\"插件: {Properties.Resources.plugin_name}\",\n                    errorMsgString);\n            };\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Properties.Resources.plugin_name;\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Properties.Resources.plugin_description;\n        }\n\n        private void OnThemeChanged(Theme oldtheme, Theme newTheme)\n        {\n            UpdateIconPath(newTheme);\n        }\n\n        private void UpdateIconPath(Theme theme)\n        {\n            if (theme == Theme.Light || theme == Theme.HighContrastWhite)\n            {\n                _iconPath = \"Images/WebSearch.light.png\";\n            }\n            else\n            {\n                _iconPath = \"Images/WebSearch.dark.png\";\n            }\n        }\n\n        public Control CreateSettingPanel()\n        {\n            throw new NotImplementedException();\n        }\n\n        public void UpdateSettings(PowerLauncherPluginSettings settings)\n        {\n            _notGlobalIfUri = settings?.AdditionalOptions?.FirstOrDefault(x => x.Key == NotGlobalIfUri)?.Value ?? false;\n        }\n\n        public void ReloadData()\n        {\n            if (_context is null)\n            {\n                return;\n            }\n\n            UpdateIconPath(_context.API.GetCurrentTheme());\n            BrowserInfo.UpdateIfTimePassed();\n        }\n\n        public void Dispose()\n        {\n            Dispose(true);\n            GC.SuppressFinalize(this);\n        }\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (!_disposed && disposing)\n            {\n                if (_context != null && _context.API != null)\n                {\n                    _context.API.ThemeChanged -= OnThemeChanged;\n                }\n\n                _disposed = true;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Community.PowerToys.Run.Plugin.WebSearch/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"plugin_browser\" xml:space=\"preserve\">\n    <value>默认浏览器</value>\n  </data>\n  <data name=\"plugin_description\" xml:space=\"preserve\">\n    <value>使用默认搜索引擎在线搜索</value>\n  </data>\n  <data name=\"plugin_global_if_uri\" xml:space=\"preserve\">\n    <value>默认唤醒时输入网址，不显示在线搜索</value>\n  </data>\n  <data name=\"plugin_in_browser\" xml:space=\"preserve\">\n    <value>打开 默认浏览器</value>\n  </data>\n  <data name=\"plugin_in_browser_name\" xml:space=\"preserve\">\n    <value>打开 {0}</value>\n    <comment>Like \"Search the web in {the browser name}\"</comment>\n  </data>\n  <data name=\"plugin_name\" xml:space=\"preserve\">\n    <value>在线搜索</value>\n  </data>\n  <data name=\"plugin_open\" xml:space=\"preserve\">\n    <value>打开 {0} 在线搜索</value>\n  </data>\n  <data name=\"plugin_search_failed\" xml:space=\"preserve\">\n    <value>无法打开 {0}</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Folder/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"wox_plugin_folder_plugin_name\" xml:space=\"preserve\">\n    <value>文件夹</value>\n  </data>\n  <data name=\"wox_plugin_folder_plugin_description\" xml:space=\"preserve\">\n    <value>浏览文件夹</value>\n  </data>\n  <data name=\"Microsoft_plugin_folder_copy_path\" xml:space=\"preserve\">\n    <value>复制路径(Ctrl+C)</value>\n  </data>\n  <data name=\"Microsoft_plugin_folder_open_in_console\" xml:space=\"preserve\">\n    <value>在命令行打开路径(Ctrl+Shift+C)</value>\n  </data>\n  <data name=\"Microsoft_plugin_folder_open_containing_folder\" xml:space=\"preserve\">\n    <value>打开所在文件夹(Ctrl+Shift+E)</value>\n  </data>\n  <data name=\"Microsoft_plugin_folder_truncation_warning_title\" xml:space=\"preserve\">\n    <value>警告：文件夹的其余搜索结果被省略。</value>\n  </data>\n  <data name=\"Microsoft_plugin_folder_truncation_warning_subtitle\" xml:space=\"preserve\">\n    <value>显示了 {0:N0} 个结果中的 {1:N0} 个</value>\n    <comment>Example: showing 25 of 540 results</comment>\n  </data>\n  <data name=\"Microsoft_plugin_folder_clipboard_failed\" xml:space=\"preserve\">\n    <value>写入剪贴板失败</value>\n  </data>\n  <data name=\"Microsoft_plugin_folder_file_open_failed\" xml:space=\"preserve\">\n    <value>无法打开文件</value>\n  </data>\n  <data name=\"wox_plugin_folder_select_folder_first_result_subtitle\" xml:space=\"preserve\">\n    <value>提示: 使用 &gt; 在文件夹内进行搜索，使用 * 作为通配符</value>\n  </data>\n  <data name=\"wox_plugin_folder_select_folder_first_result_title\" xml:space=\"preserve\">\n    <value>打开: {0}</value>\n    <comment>Open as a verb.  Open this folder. Do not translate the placeholder '{0}'.</comment>\n  </data>\n  <data name=\"wox_plugin_folder_select_folder_OpenFileOrFolder_error_message\" xml:space=\"preserve\">\n    <value>无法打开</value>\n  </data>\n  <data name=\"wox_plugin_folder_select_file_result_subtitle\" xml:space=\"preserve\">\n    <value>文件: {0}</value>\n    <comment>the arg following is file path</comment>\n  </data>\n  <data name=\"wox_plugin_folder_select_folder_result_subtitle\" xml:space=\"preserve\">\n    <value>文件夹: {0}</value>\n    <comment>the arg following is the folder path</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Main.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.IO.Abstractions;\nusing System.Linq;\nusing System.Text.RegularExpressions;\nusing System.Windows.Controls;\n\nusing ManagedCommon;\nusing Microsoft.Plugin.Indexer.DriveDetection;\nusing Microsoft.Plugin.Indexer.Interop;\nusing Microsoft.Plugin.Indexer.SearchHelper;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Wox.Infrastructure;\nusing Wox.Infrastructure.Storage;\nusing Wox.Plugin;\nusing Wox.Plugin.Logger;\n\nnamespace Microsoft.Plugin.Indexer\n{\n    internal class Main : ISettingProvider, IPlugin, ISavable, IPluginI18n, IContextMenu, IDisposable, IDelayedExecutionPlugin\n    {\n        private const string DisableDriveDetectionWarning = nameof(DisableDriveDetectionWarning);\n        private const string ExcludedPatterns = nameof(ExcludedPatterns);\n        private static readonly IFileSystem _fileSystem = new FileSystem();\n\n        // This variable contains metadata about the Plugin\n        private PluginInitContext _context;\n\n        // This variable contains information about the context menus\n        private IndexerSettings _settings;\n\n        // Contains information about the plugin stored in json format\n        private PluginJsonStorage<IndexerSettings> _storage;\n\n        // Excluded patterns settings\n        private List<string> _excludedPatterns = new List<string>();\n\n        // To access Windows Search functionalities\n        private static readonly OleDBSearch _search = new OleDBSearch();\n        private readonly WindowsSearchAPI _api = new WindowsSearchAPI(_search);\n\n        // To obtain information regarding the drives that are indexed\n        private readonly IndexerDriveDetection _driveDetection = new IndexerDriveDetection(new RegistryWrapper(), new DriveDetection.DriveInfoWrapper());\n\n        // Reserved keywords in oleDB\n        private readonly string reservedStringPattern = @\"^[\\/\\\\\\$\\%]+$|^.*[<>].*$\";\n\n        private string WarningIconPath { get; set; }\n\n        public string Name => Properties.Resources.Microsoft_plugin_indexer_plugin_name;\n\n        public string Description => Properties.Resources.Microsoft_plugin_indexer_plugin_description;\n\n        public static string PluginID => \"2140FC9819AD43A3A616E2735815C27C\";\n\n        public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()\n        {\n            new PluginAdditionalOption()\n            {\n                Key = DisableDriveDetectionWarning,\n                DisplayLabel = Properties.Resources.disable_drive_detection_warning,\n                Value = false,\n            },\n            new PluginAdditionalOption()\n            {\n                PluginOptionType = PluginAdditionalOption.AdditionalOptionType.MultilineTextbox,\n                Key = ExcludedPatterns,\n                DisplayLabel = Properties.Resources.excluded_patterns_label,\n                DisplayDescription = Properties.Resources.excluded_patterns_description,\n                PlaceholderText = Properties.Resources.excluded_patterns_placeholder,\n                TextValue = string.Empty,\n            },\n        };\n\n        private ContextMenuLoader _contextMenuLoader;\n        private bool disposedValue;\n\n        // To save the configurations of plugins\n        public void Save()\n        {\n            _storage?.Save();\n        }\n\n        // This function uses the Windows indexer and returns the list of results obtained\n        public List<Result> Query(Query query, bool isFullQuery)\n        {\n            var results = new List<Result>();\n\n            if (!string.IsNullOrEmpty(query.Search))\n            {\n                var searchQuery = query.Search;\n                if (_settings.MaxSearchCount <= 0)\n                {\n                    _settings.MaxSearchCount = 30;\n                }\n\n                var regexMatch = Regex.Match(searchQuery, reservedStringPattern);\n\n                if (!regexMatch.Success)\n                {\n                    try\n                    {\n                        if (_driveDetection.DisplayWarning())\n                        {\n                            results.Add(new Result\n                            {\n                                Title = Properties.Resources.Microsoft_plugin_indexer_drivedetectionwarning,\n                                SubTitle = Properties.Resources.Microsoft_plugin_indexer_disable_warning_in_settings,\n                                IcoPath = WarningIconPath,\n                                Action = e =>\n                                {\n                                    Helper.OpenInShell(\"ms-settings:cortana-windowssearch\");\n                                    return true;\n                                },\n                            });\n                        }\n\n                        // This uses the Microsoft.Search.Interop assembly\n                        var searchManager = new CSearchManager();\n                        var searchResultsList = _api.Search(searchQuery, searchManager, excludedPatterns: _excludedPatterns, maxCount: _settings.MaxSearchCount).ToList();\n\n                        // If the delayed execution query is not required (since the SQL query is fast) return empty results\n                        if (searchResultsList.Count == 0 && isFullQuery)\n                        {\n                            return new List<Result>();\n                        }\n\n                        foreach (var searchResult in searchResultsList)\n                        {\n                            var path = searchResult.Path;\n\n                            // Using CurrentCulture since this is user facing\n                            var toolTipTitle = string.Format(CultureInfo.CurrentCulture, \"{0} : {1}\", Properties.Resources.Microsoft_plugin_indexer_name, searchResult.Title);\n                            var toolTipText = string.Format(CultureInfo.CurrentCulture, \"{0} : {1}\", Properties.Resources.Microsoft_plugin_indexer_path, path);\n                            string workingDir = null;\n                            if (_settings.UseLocationAsWorkingDir)\n                            {\n                                workingDir = _fileSystem.Path.GetDirectoryName(path);\n                            }\n\n                            Result r = new Result();\n                            r.Title = searchResult.Title;\n                            r.SubTitle = Properties.Resources.Microsoft_plugin_indexer_subtitle_header + \": \" + path;\n                            r.IcoPath = path;\n                            r.ToolTipData = new ToolTipData(toolTipTitle, toolTipText);\n                            r.Action = c =>\n                            {\n                                bool hide = true;\n                                if (!Helper.OpenInShell(path, null, workingDir))\n                                {\n                                    hide = false;\n                                    var name = $\"插件: {_context.CurrentPluginMetadata.Name}\";\n                                    var msg = Properties.Resources.Microsoft_plugin_indexer_file_open_failed;\n                                    _context.API.ShowMsg(name, msg, string.Empty);\n                                }\n\n                                return hide;\n                            };\n                            r.ContextData = searchResult;\n\n                            // If the result is a directory, then its display should show a directory.\n                            if (_fileSystem.Directory.Exists(path))\n                            {\n                                r.QueryTextDisplay = path;\n                            }\n\n                            results.Add(r);\n                        }\n                    }\n                    catch (InvalidOperationException)\n                    {\n                        // The connection has closed, internal error of ExecuteReader()\n                        // Not showing this exception to the users\n                    }\n                    catch (Exception ex)\n                    {\n                        Log.Exception(\"Something failed\", ex, GetType());\n                    }\n                }\n            }\n\n            return results;\n        }\n\n        // This function uses the Windows indexer and returns the list of results obtained. This version is required to implement the interface\n        public List<Result> Query(Query query)\n        {\n            // All plugins have to implement IPlugin interface. We return empty collection as we do not want any computation with constant search plugins.\n            return new List<Result>();\n        }\n\n        public void Init(PluginInitContext context)\n        {\n            // initialize the context of the plugin\n            _context = context;\n            _contextMenuLoader = new ContextMenuLoader(context);\n            _storage = new PluginJsonStorage<IndexerSettings>();\n            _settings = _storage.Load();\n            _context.API.ThemeChanged += OnThemeChanged;\n            UpdateIconPath(_context.API.GetCurrentTheme());\n        }\n\n        // Todo : Update with theme based IconPath\n        private void UpdateIconPath(Theme theme)\n        {\n            if (theme == Theme.Light || theme == Theme.HighContrastWhite)\n            {\n                WarningIconPath = \"Images/Warning.light.png\";\n            }\n            else\n            {\n                WarningIconPath = \"Images/Warning.dark.png\";\n            }\n        }\n\n        private void OnThemeChanged(Theme currentTheme, Theme newTheme)\n        {\n            UpdateIconPath(newTheme);\n        }\n\n        // Set the Plugin Title\n        public string GetTranslatedPluginTitle()\n        {\n            return Properties.Resources.Microsoft_plugin_indexer_plugin_name;\n        }\n\n        // Set the plugin Description\n        public string GetTranslatedPluginDescription()\n        {\n            return Properties.Resources.Microsoft_plugin_indexer_plugin_description;\n        }\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            return _contextMenuLoader.LoadContextMenus(selectedResult);\n        }\n\n        public void UpdateSettings(PowerLauncherPluginSettings settings)\n        {\n            var driveDetection = false;\n\n            if (settings.AdditionalOptions != null)\n            {\n                var driveDetectionOption = settings.AdditionalOptions.FirstOrDefault(x => x.Key == DisableDriveDetectionWarning);\n\n                driveDetection = driveDetectionOption == null ? false : driveDetectionOption.Value;\n\n                var excludedPatternsOption = settings.AdditionalOptions.FirstOrDefault(x => x.Key == ExcludedPatterns);\n\n                _excludedPatterns = excludedPatternsOption == null ? new List<string>() : excludedPatternsOption.TextValueAsMultilineList;\n            }\n\n            _driveDetection.IsDriveDetectionWarningCheckBoxSelected = driveDetection;\n        }\n\n        public Control CreateSettingPanel()\n        {\n            throw new NotImplementedException();\n        }\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (!disposedValue)\n            {\n                if (disposing)\n                {\n                }\n\n                disposedValue = true;\n            }\n        }\n\n        public void Dispose()\n        {\n            // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method\n            Dispose(disposing: true);\n            GC.SuppressFinalize(this);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Indexer/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Microsoft_plugin_indexer_copy_path\" xml:space=\"preserve\">\n    <value>复制路径(Ctrl+C)</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_open_containing_folder\" xml:space=\"preserve\">\n    <value>打开所在文件夹(Ctrl+Shift+E)</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_run_as_administrator\" xml:space=\"preserve\">\n    <value>以管理员身份打开(Ctrl+Shift+Enter)</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_open_in_console\" xml:space=\"preserve\">\n    <value>在命令行打开路径(Ctrl+Shift+C)</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_name\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_path\" xml:space=\"preserve\">\n    <value>路径</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_drivedetectionwarning\" xml:space=\"preserve\">\n    <value>警告：未完全建立索引，搜索结果可能不全。</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_disable_warning_in_settings\" xml:space=\"preserve\">\n    <value>单击转到 Windows 搜索设置进行修复。</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_clipboard_failed\" xml:space=\"preserve\">\n    <value>写入剪贴板失败</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_file_open_failed\" xml:space=\"preserve\">\n    <value>无法打开文件</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_folder_open_failed\" xml:space=\"preserve\">\n    <value>无法打开文件夹</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_plugin_description\" xml:space=\"preserve\">\n    <value>搜索文件与文件夹</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_plugin_name\" xml:space=\"preserve\">\n    <value>搜索</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_subtitle_header\" xml:space=\"preserve\">\n    <value>搜索</value>\n  </data>\n  <data name=\"disable_drive_detection_warning\" xml:space=\"preserve\">\n    <value>不显示未索引文件警告</value>\n  </data>\n  <data name=\"Microsoft_plugin_indexer_run_as_user\" xml:space=\"preserve\">\n    <value>以其他用户身份打开(Ctrl+Shift+U)</value>\n  </data>\n  <data name=\"excluded_patterns_label\" xml:space=\"preserve\">\n    <value>排除规则</value>\n  </data>\n  <data name=\"excluded_patterns_description\" xml:space=\"preserve\">\n    <value>填写要排除的文件名规则，每行一个，名称符合的文件和文件夹将会被隐藏</value>\n  </data>\n  <data name=\"excluded_patterns_placeholder\" xml:space=\"preserve\">\n    <value>例如: *.exe</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nusing ManagedCommon;\nusing Microsoft.Plugin.Program.ProgramArgumentParser;\nusing Microsoft.Plugin.Program.Programs;\nusing Microsoft.Plugin.Program.Storage;\nusing Wox.Infrastructure.Storage;\nusing Wox.Plugin;\nusing Wox.Plugin.Common;\n\nusing Stopwatch = Wox.Infrastructure.Stopwatch;\n\nnamespace Microsoft.Plugin.Program\n{\n    public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IDisposable\n    {\n        // The order of this array is important! The Parsers will be checked in order (index 0 to index Length-1) and the first parser which is able to parse the Query will be used\n        // NoArgumentsArgumentParser does always succeed and therefore should always be last/fallback\n        private static readonly IProgramArgumentParser[] _programArgumentParsers = new IProgramArgumentParser[]\n        {\n            new DoubleDashProgramArgumentParser(),\n            new InferredProgramArgumentParser(),\n            new NoArgumentsArgumentParser(),\n        };\n\n        internal static ProgramPluginSettings Settings { get; set; }\n\n        internal static readonly ShellLocalization ShellLocalizationHelper = new();\n\n        public string Name => Properties.Resources.wox_plugin_program_plugin_name;\n\n        public string Description => Properties.Resources.wox_plugin_program_plugin_description;\n\n        public static string PluginID => \"791FC278BA414111B8D1886DFE447410\";\n\n        private static PluginInitContext _context;\n        private readonly PluginJsonStorage<ProgramPluginSettings> _settingsStorage;\n        private bool _disposed;\n        private PackageRepository _packageRepository;\n        private static Win32ProgramFileSystemWatchers _win32ProgramRepositoryHelper;\n        private static Win32ProgramRepository _win32ProgramRepository;\n\n        public Main()\n        {\n            _settingsStorage = new PluginJsonStorage<ProgramPluginSettings>();\n            Settings = _settingsStorage.Load();\n\n            // This helper class initializes the file system watchers based on the locations to watch\n            _win32ProgramRepositoryHelper = new Win32ProgramFileSystemWatchers();\n\n            // Initialize the Win32ProgramRepository with the settings object\n            _win32ProgramRepository = new Win32ProgramRepository(_win32ProgramRepositoryHelper.FileSystemWatchers.Cast<IFileSystemWatcherWrapper>().ToList(), Settings, _win32ProgramRepositoryHelper.PathsToWatch);\n        }\n\n        public void Save()\n        {\n            _settingsStorage.Save();\n        }\n\n        public List<Result> Query(Query query)\n        {\n            var sources = _programArgumentParsers\n                .Where(programArgumentParser => programArgumentParser.Enabled);\n\n            foreach (var programArgumentParser in sources)\n            {\n                if (!programArgumentParser.TryParse(query, out var program, out var programArguments))\n                {\n                    continue;\n                }\n\n                return Query(program, programArguments).ToList();\n            }\n\n            return new List<Result>(0);\n        }\n\n        private IEnumerable<Result> Query(string program, string programArguments)\n        {\n            var result = _win32ProgramRepository\n                .Concat<IProgram>(_packageRepository)\n                .AsParallel()\n                .Where(p => p.Enabled)\n                .Select(p => p.Result(program, programArguments, _context.API))\n                .Where(r => r?.Score > 0)\n                .ToArray();\n\n            if (result.Length != 0)\n            {\n                var maxScore = result.Max(x => x.Score);\n                return result\n                    .Where(x => x.Score > Settings.MinScoreThreshold * maxScore);\n            }\n\n            return Enumerable.Empty<Result>();\n        }\n\n        public void Init(PluginInitContext context)\n        {\n            _context = context ?? throw new ArgumentNullException(nameof(context));\n            _context.API.ThemeChanged += OnThemeChanged;\n            _packageRepository = new PackageRepository(new PackageCatalogWrapper(), _context);\n\n            var a = Task.Run(() =>\n            {\n                Stopwatch.Normal(\"Microsoft.Plugin.Program.Main - Win32Program index cost\", _win32ProgramRepository.IndexPrograms);\n            });\n\n            var b = Task.Run(() =>\n            {\n                Stopwatch.Normal(\"Microsoft.Plugin.Program.Main - Package index cost\", _packageRepository.IndexPrograms);\n                UpdateUWPIconPath(_context.API.GetCurrentTheme());\n            });\n\n            Task.WaitAll(a, b);\n\n            Settings.LastIndexTime = DateTime.Today;\n        }\n\n        public void OnThemeChanged(Theme currentTheme, Theme newTheme)\n        {\n            UpdateUWPIconPath(newTheme);\n        }\n\n        public void UpdateUWPIconPath(Theme theme)\n        {\n            if (_packageRepository != null)\n            {\n                foreach (UWPApplication app in _packageRepository)\n                {\n                    app.UpdateLogoPath(theme);\n                }\n            }\n        }\n\n        public void IndexPrograms()\n        {\n            var t1 = Task.Run(() => _win32ProgramRepository.IndexPrograms());\n            var t2 = Task.Run(() => _packageRepository.IndexPrograms());\n\n            Task.WaitAll(t1, t2);\n\n            Settings.LastIndexTime = DateTime.Today;\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Properties.Resources.wox_plugin_program_plugin_name;\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Properties.Resources.wox_plugin_program_plugin_description;\n        }\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            ArgumentNullException.ThrowIfNull(selectedResult);\n\n            var menuOptions = new List<ContextMenuResult>();\n            if (selectedResult.ContextData is IProgram program)\n            {\n                menuOptions = program.ContextMenus(selectedResult.ProgramArguments, _context.API);\n            }\n\n            return menuOptions;\n        }\n\n        public static void StartProcess(Func<ProcessStartInfo, Process> runProcess, ProcessStartInfo info)\n        {\n            try\n            {\n                ArgumentNullException.ThrowIfNull(runProcess);\n\n                ArgumentNullException.ThrowIfNull(info);\n\n                runProcess(info);\n            }\n            catch (Exception ex)\n            {\n                Logger.ProgramLogger.Exception($\"Unable to start \", ex, System.Reflection.MethodBase.GetCurrentMethod().DeclaringType, info?.FileName);\n                var name = \"插件: \" + Properties.Resources.wox_plugin_program_plugin_name;\n                var message = $\"{Properties.Resources.powertoys_run_plugin_program_start_failed}: {info?.FileName}\";\n                _context.API.ShowMsg(name, message, string.Empty);\n            }\n        }\n\n        public void Dispose()\n        {\n            Dispose(disposing: true);\n            GC.SuppressFinalize(this);\n        }\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (!_disposed)\n            {\n                if (disposing)\n                {\n                    if (_context != null && _context.API != null)\n                    {\n                        _context.API.ThemeChanged -= OnThemeChanged;\n                    }\n\n                    _win32ProgramRepositoryHelper?.Dispose();\n                    _disposed = true;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.IO.Abstractions;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Xml;\n\nusing ManagedCommon;\nusing Microsoft.Plugin.Program.Logger;\nusing Wox.Infrastructure;\nusing Wox.Infrastructure.Image;\nusing Wox.Plugin;\nusing Wox.Plugin.Common;\nusing Wox.Plugin.Common.Win32;\nusing Wox.Plugin.Logger;\n\nusing PackageVersion = Microsoft.Plugin.Program.Programs.UWP.PackageVersion;\n\nnamespace Microsoft.Plugin.Program.Programs\n{\n    [Serializable]\n    public class UWPApplication : IProgram\n    {\n        private static readonly IFileSystem FileSystem = new FileSystem();\n        private static readonly IPath Path = FileSystem.Path;\n        private static readonly IFile File = FileSystem.File;\n\n        public string AppListEntry { get; set; }\n\n        public string UniqueIdentifier { get; set; }\n\n        public string DisplayName { get; set; }\n\n        public string Description { get; set; }\n\n        public string UserModelId { get; set; }\n\n        public string BackgroundColor { get; set; }\n\n        public string EntryPoint { get; set; }\n\n        public string Name => DisplayName;\n\n        public string Location => Package.Location;\n\n        // Localized path based on windows display language\n        public string LocationLocalized => Package.LocationLocalized;\n\n        public bool Enabled { get; set; }\n\n        public bool CanRunElevated { get; set; }\n\n        public string LogoPath { get; set; }\n\n        public LogoType LogoType { get; set; }\n\n        public UWP Package { get; set; }\n\n        private string logoUri;\n\n        private const string ContrastWhite = \"contrast-white\";\n\n        private const string ContrastBlack = \"contrast-black\";\n\n        // Function to calculate the score of a result\n        private int Score(string query)\n        {\n            var displayNameMatch = StringMatcher.FuzzySearch(query, DisplayName);\n            var descriptionMatch = StringMatcher.FuzzySearch(query, Description);\n            var score = new[] { displayNameMatch.Score, descriptionMatch.Score / 2 }.Max();\n            return score;\n        }\n\n        // Function to set the subtitle based on the Type of application\n        private static string SetSubtitle()\n        {\n            return Properties.Resources.powertoys_run_plugin_program_packaged_application;\n        }\n\n        public Result Result(string query, string queryArguments, IPublicAPI api)\n        {\n            ArgumentNullException.ThrowIfNull(api);\n\n            var score = Score(query);\n            if (score <= 0)\n            { // no need to create result if score is 0\n                return null;\n            }\n\n            var result = new Result\n            {\n                SubTitle = SetSubtitle(),\n                Icon = Logo,\n                Score = score,\n                ContextData = this,\n                ProgramArguments = queryArguments,\n                Action = e =>\n                {\n                    Launch(api, queryArguments);\n                    return true;\n                },\n            };\n\n            // To set the title to always be the displayname of the packaged application\n            result.Title = DisplayName;\n            result.TitleHighlightData = StringMatcher.FuzzySearch(query, Name).MatchData;\n\n            // Using CurrentCulture since this is user facing\n            var toolTipTitle = result.Title;\n            var toolTipText = LocationLocalized;\n            result.ToolTipData = new ToolTipData(toolTipTitle, toolTipText);\n\n            return result;\n        }\n\n        public List<ContextMenuResult> ContextMenus(string queryArguments, IPublicAPI api)\n        {\n            ArgumentNullException.ThrowIfNull(api);\n\n            var contextMenus = new List<ContextMenuResult>();\n\n            if (CanRunElevated)\n            {\n                contextMenus.Add(\n                        new ContextMenuResult\n                        {\n                            PluginName = Assembly.GetExecutingAssembly().GetName().Name,\n                            Title = Properties.Resources.wox_plugin_program_run_as_administrator,\n                            Glyph = \"\\xE7EF\",\n                            FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                            AcceleratorKey = Key.Enter,\n                            AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                            Action = _ =>\n                            {\n                                string command = \"shell:AppsFolder\\\\\" + UniqueIdentifier;\n                                command = Environment.ExpandEnvironmentVariables(command.Trim());\n\n                                var info = ShellCommand.SetProcessStartInfo(command, verb: \"runas\");\n                                info.UseShellExecute = true;\n                                info.Arguments = queryArguments;\n                                Process.Start(info);\n                                return true;\n                            },\n                        });\n\n                // We don't add context menu to 'run as different user', because UWP applications normally installed per user and not for all users.\n            }\n\n            contextMenus.Add(\n                new ContextMenuResult\n                {\n                    PluginName = Assembly.GetExecutingAssembly().GetName().Name,\n                    Title = Properties.Resources.wox_plugin_program_open_containing_folder,\n                    Glyph = \"\\xE838\",\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    AcceleratorKey = Key.E,\n                    AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                    Action = _ =>\n                    {\n                        Helper.OpenInShell(Package.Location);\n\n                        return true;\n                    },\n                });\n\n            contextMenus.Add(new ContextMenuResult\n            {\n                PluginName = Assembly.GetExecutingAssembly().GetName().Name,\n                Title = Properties.Resources.wox_plugin_program_open_in_console,\n                Glyph = \"\\xE756\",\n                FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                AcceleratorKey = Key.C,\n                AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                Action = (context) =>\n                {\n                    try\n                    {\n                        Helper.OpenInConsole(Package.Location);\n                        return true;\n                    }\n                    catch (Exception e)\n                    {\n                        Log.Exception($\"Failed to open {Name} in console, {e.Message}\", e, GetType());\n                        return false;\n                    }\n                },\n            });\n\n            return contextMenus;\n        }\n\n        private async void Launch(IPublicAPI api, string queryArguments)\n        {\n            var appManager = new ApplicationActivationHelper.ApplicationActivationManager();\n            const ApplicationActivationHelper.ActivateOptions noFlags = ApplicationActivationHelper.ActivateOptions.None;\n            await Task.Run(() =>\n            {\n                try\n                {\n                    appManager.ActivateApplication(UserModelId, queryArguments, noFlags, out var unusedPid);\n                }\n                catch (Exception ex)\n                {\n                    ProgramLogger.Exception($\"Unable to launch UWP {DisplayName}\", ex, MethodBase.GetCurrentMethod().DeclaringType, queryArguments);\n                    var name = \"插件: \" + Properties.Resources.wox_plugin_program_plugin_name;\n                    var message = $\"{Properties.Resources.powertoys_run_plugin_program_uwp_failed}: {DisplayName}\";\n                    api.ShowMsg(name, message, string.Empty);\n                }\n            }).ConfigureAwait(false);\n        }\n\n        public UWPApplication(IAppxManifestApplication manifestApp, UWP package)\n        {\n            ArgumentNullException.ThrowIfNull(manifestApp);\n\n            var hr = manifestApp.GetAppUserModelId(out var tmpUserModelId);\n            UserModelId = AppxPackageHelper.CheckHRAndReturnOrThrow(hr, tmpUserModelId);\n\n            hr = manifestApp.GetAppUserModelId(out var tmpUniqueIdentifier);\n            UniqueIdentifier = AppxPackageHelper.CheckHRAndReturnOrThrow(hr, tmpUniqueIdentifier);\n\n            hr = manifestApp.GetStringValue(\"DisplayName\", out var tmpDisplayName);\n            DisplayName = AppxPackageHelper.CheckHRAndReturnOrThrow(hr, tmpDisplayName);\n\n            hr = manifestApp.GetStringValue(\"Description\", out var tmpDescription);\n            Description = AppxPackageHelper.CheckHRAndReturnOrThrow(hr, tmpDescription);\n\n            hr = manifestApp.GetStringValue(\"BackgroundColor\", out var tmpBackgroundColor);\n            BackgroundColor = AppxPackageHelper.CheckHRAndReturnOrThrow(hr, tmpBackgroundColor);\n\n            hr = manifestApp.GetStringValue(\"EntryPoint\", out var tmpEntryPoint);\n            EntryPoint = AppxPackageHelper.CheckHRAndReturnOrThrow(hr, tmpEntryPoint);\n\n            Package = package ?? throw new ArgumentNullException(nameof(package));\n\n            DisplayName = ResourceFromPri(package.FullName, DisplayName);\n            Description = ResourceFromPri(package.FullName, Description);\n            logoUri = LogoUriFromManifest(manifestApp);\n\n            Enabled = true;\n            CanRunElevated = IfApplicationCanRunElevated();\n        }\n\n        private bool IfApplicationCanRunElevated()\n        {\n            if (EntryPoint == \"Windows.FullTrustApplication\")\n            {\n                return true;\n            }\n            else\n            {\n                var manifest = Package.Location + \"\\\\AppxManifest.xml\";\n                if (File.Exists(manifest))\n                {\n                    try\n                    {\n                        // Check the manifest to verify if the Trust Level for the application is \"mediumIL\"\n                        var file = File.ReadAllText(manifest);\n                        var xmlDoc = new XmlDocument();\n                        xmlDoc.LoadXml(file);\n                        var xmlRoot = xmlDoc.DocumentElement;\n                        var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);\n                        namespaceManager.AddNamespace(\"uap10\", \"http://schemas.microsoft.com/appx/manifest/uap/windows10/10\");\n                        var trustLevelNode = xmlRoot.SelectSingleNode(\"//*[local-name()='Application' and @uap10:TrustLevel]\", namespaceManager); // According to https://learn.microsoft.com/windows/apps/desktop/modernize/grant-identity-to-nonpackaged-apps#create-a-package-manifest-for-the-sparse-package and https://learn.microsoft.com/uwp/schemas/appxpackage/uapmanifestschema/element-application#attributes\n\n                        if (trustLevelNode?.Attributes[\"uap10:TrustLevel\"]?.Value == \"mediumIL\")\n                        {\n                            return true;\n                        }\n                    }\n                    catch (Exception e)\n                    {\n                        ProgramLogger.Exception($\"Unable to parse manifest file for {DisplayName}\", e, MethodBase.GetCurrentMethod().DeclaringType, manifest);\n                    }\n                }\n            }\n\n            return false;\n        }\n\n        internal string ResourceFromPri(string packageFullName, string resourceReference)\n        {\n            const string prefix = \"ms-resource:\";\n\n            // Using OrdinalIgnoreCase since this is used internally\n            if (!string.IsNullOrWhiteSpace(resourceReference) && resourceReference.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))\n            {\n                // magic comes from @talynone\n                // https://github.com/talynone/Wox.Plugin.WindowsUniversalAppLauncher/blob/master/StoreAppLauncher/Helpers/NativeApiHelper.cs#L139-L153\n                string key = resourceReference.Substring(prefix.Length);\n                string parsed;\n                string parsedFallback = string.Empty;\n\n                // Using Ordinal/OrdinalIgnoreCase since these are used internally\n                if (key.StartsWith(\"//\", StringComparison.Ordinal))\n                {\n                    parsed = prefix + key;\n                }\n                else if (key.StartsWith('/'))\n                {\n                    parsed = prefix + \"//\" + key;\n                }\n                else if (key.Contains(\"resources\", StringComparison.OrdinalIgnoreCase))\n                {\n                    parsed = prefix + key;\n                }\n                else\n                {\n                    parsed = prefix + \"///resources/\" + key;\n\n                    // e.g. for Windows Terminal version >= 1.12 DisplayName and Description resources are not in the 'resources' subtree\n                    parsedFallback = prefix + \"///\" + key;\n                }\n\n                var outBuffer = new StringBuilder(128);\n                string source = $\"@{{{packageFullName}? {parsed}}}\";\n                var capacity = (uint)outBuffer.Capacity;\n                var hResult = NativeMethods.SHLoadIndirectString(source, outBuffer, capacity, IntPtr.Zero);\n                if (hResult != HRESULT.S_OK)\n                {\n                    if (!string.IsNullOrEmpty(parsedFallback))\n                    {\n                        string sourceFallback = $\"@{{{packageFullName}? {parsedFallback}}}\";\n                        hResult = NativeMethods.SHLoadIndirectString(sourceFallback, outBuffer, capacity, IntPtr.Zero);\n                        if (hResult == HRESULT.S_OK)\n                        {\n                            var loaded = outBuffer.ToString();\n                            if (!string.IsNullOrEmpty(loaded))\n                            {\n                                return loaded;\n                            }\n                            else\n                            {\n                                ProgramLogger.Exception($\"Can't load null or empty result pri {sourceFallback} in uwp location {Package.Location}\", new ArgumentNullException(null), GetType(), Package.Location);\n\n                                return string.Empty;\n                            }\n                        }\n                    }\n\n                    // https://github.com/Wox-launcher/Wox/issues/964\n                    // known hresult 2147942522:\n                    // 'Microsoft Corporation' violates pattern constraint of '\\bms-resource:.{1,256}'.\n                    // for\n                    // Microsoft.MicrosoftOfficeHub_17.7608.23501.0_x64__8wekyb3d8bbwe: ms-resource://Microsoft.MicrosoftOfficeHub/officehubintl/AppManifest_GetOffice_Description\n                    // Microsoft.BingFoodAndDrink_3.0.4.336_x64__8wekyb3d8bbwe: ms-resource:AppDescription\n                    var e = Marshal.GetExceptionForHR((int)hResult);\n                    ProgramLogger.Exception($\"Load pri failed {source} with HResult {hResult} and location {Package.Location}\", e, GetType(), Package.Location);\n\n                    return string.Empty;\n                }\n                else\n                {\n                    var loaded = outBuffer.ToString();\n                    if (!string.IsNullOrEmpty(loaded))\n                    {\n                        return loaded;\n                    }\n                    else\n                    {\n                        ProgramLogger.Exception($\"Can't load null or empty result pri {source} in uwp location {Package.Location}\", new ArgumentNullException(null), GetType(), Package.Location);\n\n                        return string.Empty;\n                    }\n                }\n            }\n            else\n            {\n                return resourceReference;\n            }\n        }\n\n        private static readonly Dictionary<PackageVersion, string> _logoKeyFromVersion = new Dictionary<PackageVersion, string>\n        {\n            { PackageVersion.Windows10, \"Square44x44Logo\" },\n            { PackageVersion.Windows81, \"Square30x30Logo\" },\n            { PackageVersion.Windows8, \"SmallLogo\" },\n        };\n\n        internal string LogoUriFromManifest(IAppxManifestApplication app)\n        {\n            if (_logoKeyFromVersion.TryGetValue(Package.Version, out var key))\n            {\n                var hr = app.GetStringValue(key, out var logoUriFromApp);\n                _ = AppxPackageHelper.CheckHRAndReturnOrThrow(hr, logoUriFromApp);\n                return logoUriFromApp;\n            }\n            else\n            {\n                return string.Empty;\n            }\n        }\n\n        public void UpdateLogoPath(Theme theme)\n        {\n            LogoPathFromUri(logoUri, theme);\n        }\n\n        // scale factors on win10: https://learn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets#asset-size-tables,\n        private static readonly Dictionary<PackageVersion, List<int>> _scaleFactors = new Dictionary<PackageVersion, List<int>>\n        {\n            { PackageVersion.Windows10, new List<int> { 100, 125, 150, 200, 400 } },\n            { PackageVersion.Windows81, new List<int> { 100, 120, 140, 160, 180 } },\n            { PackageVersion.Windows8, new List<int> { 100 } },\n        };\n\n        private bool SetScaleIcons(string path, string colorscheme, bool highContrast = false)\n        {\n            var extension = Path.GetExtension(path);\n            if (extension != null)\n            {\n                var end = path.Length - extension.Length;\n                var prefix = path.Substring(0, end);\n                var paths = new List<string> { };\n\n                if (!highContrast)\n                {\n                    paths.Add(path);\n                }\n\n                if (_scaleFactors.TryGetValue(Package.Version, out List<int> factors))\n                {\n                    foreach (var factor in factors)\n                    {\n                        if (highContrast)\n                        {\n                            paths.Add($\"{prefix}.scale-{factor}_{colorscheme}{extension}\");\n                            paths.Add($\"{prefix}.{colorscheme}_scale-{factor}{extension}\");\n                        }\n                        else\n                        {\n                            paths.Add($\"{prefix}.scale-{factor}{extension}\");\n                        }\n                    }\n                }\n\n                var selectedIconPath = paths.FirstOrDefault(File.Exists);\n                if (!string.IsNullOrEmpty(selectedIconPath))\n                {\n                    LogoPath = selectedIconPath;\n                    if (highContrast)\n                    {\n                        LogoType = LogoType.HighContrast;\n                    }\n                    else\n                    {\n                        LogoType = LogoType.Colored;\n                    }\n\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        private bool SetTargetSizeIcon(string path, string colorscheme, bool highContrast = false)\n        {\n            var extension = Path.GetExtension(path);\n            if (extension != null)\n            {\n                var end = path.Length - extension.Length;\n                var prefix = path.Substring(0, end);\n                var paths = new List<string> { };\n                const int appIconSize = 36;\n                var targetSizes = new List<int> { 16, 24, 30, 36, 44, 60, 72, 96, 128, 180, 256 }.AsParallel();\n                var pathFactorPairs = new Dictionary<string, int>();\n\n                foreach (var factor in targetSizes)\n                {\n                    if (highContrast)\n                    {\n                        string suffixThemePath = $\"{prefix}.targetsize-{factor}_{colorscheme}{extension}\";\n                        string prefixThemePath = $\"{prefix}.{colorscheme}_targetsize-{factor}{extension}\";\n                        paths.Add(suffixThemePath);\n                        paths.Add(prefixThemePath);\n                        pathFactorPairs.Add(suffixThemePath, factor);\n                        pathFactorPairs.Add(prefixThemePath, factor);\n                    }\n                    else\n                    {\n                        string simplePath = $\"{prefix}.targetsize-{factor}{extension}\";\n                        string altformUnPlatedPath = $\"{prefix}.targetsize-{factor}_altform-unplated{extension}\";\n                        paths.Add(simplePath);\n                        paths.Add(altformUnPlatedPath);\n                        pathFactorPairs.Add(simplePath, factor);\n                        pathFactorPairs.Add(altformUnPlatedPath, factor);\n                    }\n                }\n\n                var selectedIconPath = paths.OrderBy(x => Math.Abs(pathFactorPairs.GetValueOrDefault(x) - appIconSize)).FirstOrDefault(File.Exists);\n                if (!string.IsNullOrEmpty(selectedIconPath))\n                {\n                    LogoPath = selectedIconPath;\n                    if (highContrast)\n                    {\n                        LogoType = LogoType.HighContrast;\n                    }\n                    else\n                    {\n                        LogoType = LogoType.Colored;\n                    }\n\n                    return true;\n                }\n            }\n\n            return false;\n        }\n\n        private bool SetColoredIcon(string path, string colorscheme)\n        {\n            var isSetColoredScaleIcon = SetScaleIcons(path, colorscheme);\n            if (isSetColoredScaleIcon)\n            {\n                return true;\n            }\n\n            var isSetColoredTargetIcon = SetTargetSizeIcon(path, colorscheme);\n            if (isSetColoredTargetIcon)\n            {\n                return true;\n            }\n\n            var isSetHighContrastScaleIcon = SetScaleIcons(path, colorscheme, true);\n            if (isSetHighContrastScaleIcon)\n            {\n                return true;\n            }\n\n            var isSetHighContrastTargetIcon = SetTargetSizeIcon(path, colorscheme, true);\n            if (isSetHighContrastTargetIcon)\n            {\n                return true;\n            }\n\n            return false;\n        }\n\n        private bool SetHighContrastIcon(string path, string colorscheme)\n        {\n            var isSetHighContrastScaleIcon = SetScaleIcons(path, colorscheme, true);\n            if (isSetHighContrastScaleIcon)\n            {\n                return true;\n            }\n\n            var isSetHighContrastTargetIcon = SetTargetSizeIcon(path, colorscheme, true);\n            if (isSetHighContrastTargetIcon)\n            {\n                return true;\n            }\n\n            var isSetColoredScaleIcon = SetScaleIcons(path, colorscheme);\n            if (isSetColoredScaleIcon)\n            {\n                return true;\n            }\n\n            var isSetColoredTargetIcon = SetTargetSizeIcon(path, colorscheme);\n            if (isSetColoredTargetIcon)\n            {\n                return true;\n            }\n\n            return false;\n        }\n\n        internal void LogoPathFromUri(string uri, Theme theme)\n        {\n            // all https://learn.microsoft.com/windows/uwp/controls-and-patterns/tiles-and-notifications-app-assets\n            // windows 10 https://msdn.microsoft.com/library/windows/apps/dn934817.aspx\n            // windows 8.1 https://msdn.microsoft.com/library/windows/apps/hh965372.aspx#target_size\n            // windows 8 https://msdn.microsoft.com/library/windows/apps/br211475.aspx\n            string path;\n            bool isLogoUriSet;\n\n            // Using Ordinal since this is used internally with uri\n            if (uri.Contains('\\\\', StringComparison.Ordinal))\n            {\n                path = Path.Combine(Package.Location, uri);\n            }\n            else\n            {\n                // for C:\\Windows\\MiracastView etc\n                path = Path.Combine(Package.Location, \"Assets\", uri);\n            }\n\n            switch (theme)\n            {\n                case Theme.HighContrastBlack:\n                case Theme.HighContrastOne:\n                case Theme.HighContrastTwo:\n                    isLogoUriSet = SetHighContrastIcon(path, ContrastBlack);\n                    break;\n                case Theme.HighContrastWhite:\n                    isLogoUriSet = SetHighContrastIcon(path, ContrastWhite);\n                    break;\n                case Theme.Light:\n                    isLogoUriSet = SetColoredIcon(path, ContrastWhite);\n                    break;\n                default:\n                    isLogoUriSet = SetColoredIcon(path, ContrastBlack);\n                    break;\n            }\n\n            if (!isLogoUriSet)\n            {\n                LogoPath = string.Empty;\n                LogoType = LogoType.Error;\n                ProgramLogger.Exception($\"|{UserModelId} can't find logo uri for {uri} in package location: {Package.Location}\", new FileNotFoundException(), GetType(), Package.Location);\n            }\n        }\n\n        public ImageSource Logo()\n        {\n            if (LogoType == LogoType.Colored)\n            {\n                var logo = ImageFromPath(LogoPath);\n                var platedImage = PlatedImage(logo);\n                return platedImage;\n            }\n            else\n            {\n                return ImageFromPath(LogoPath);\n            }\n        }\n\n        private const int _dpiScale100 = 96;\n\n        private ImageSource PlatedImage(BitmapImage image)\n        {\n            if (!string.IsNullOrEmpty(BackgroundColor))\n            {\n                string currentBackgroundColor;\n                if (BackgroundColor == \"transparent\")\n                {\n                    // Using InvariantCulture since this is internal\n                    currentBackgroundColor = SystemParameters.WindowGlassBrush.ToString(CultureInfo.InvariantCulture);\n                }\n                else\n                {\n                    currentBackgroundColor = BackgroundColor;\n                }\n\n                var padding = 8;\n                var width = image.Width + (2 * padding);\n                var height = image.Height + (2 * padding);\n                var x = 0;\n                var y = 0;\n\n                var group = new DrawingGroup();\n                var converted = ColorConverter.ConvertFromString(currentBackgroundColor);\n                if (converted != null)\n                {\n                    var color = (Color)converted;\n                    var brush = new SolidColorBrush(color);\n                    var pen = new Pen(brush, 1);\n                    var backgroundArea = new Rect(0, 0, width, height);\n                    var rectangleGeometry = new RectangleGeometry(backgroundArea, 8, 8);\n                    var rectDrawing = new GeometryDrawing(brush, pen, rectangleGeometry);\n                    group.Children.Add(rectDrawing);\n\n                    var imageArea = new Rect(x + padding, y + padding, image.Width, image.Height);\n                    var imageDrawing = new ImageDrawing(image, imageArea);\n                    group.Children.Add(imageDrawing);\n\n                    // http://stackoverflow.com/questions/6676072/get-system-drawing-bitmap-of-a-wpf-area-using-visualbrush\n                    var visual = new DrawingVisual();\n                    var context = visual.RenderOpen();\n                    context.DrawDrawing(group);\n                    context.Close();\n\n                    var bitmap = new RenderTargetBitmap(\n                        Convert.ToInt32(width),\n                        Convert.ToInt32(height),\n                        _dpiScale100,\n                        _dpiScale100,\n                        PixelFormats.Pbgra32);\n\n                    bitmap.Render(visual);\n\n                    return bitmap;\n                }\n                else\n                {\n                    ProgramLogger.Exception($\"Unable to convert background string {BackgroundColor} to color for {Package.Location}\", new InvalidOperationException(), GetType(), Package.Location);\n\n                    return new BitmapImage(new Uri(Constant.ErrorIcon));\n                }\n            }\n            else\n            {\n                // todo use windows theme as background\n                return image;\n            }\n        }\n\n        private BitmapImage ImageFromPath(string path)\n        {\n            if (File.Exists(path))\n            {\n                var memoryStream = new MemoryStream();\n                using (var fileStream = File.OpenRead(path))\n                {\n                    fileStream.CopyTo(memoryStream);\n                    memoryStream.Position = 0;\n\n                    var image = new BitmapImage();\n                    image.BeginInit();\n                    image.StreamSource = memoryStream;\n                    image.EndInit();\n                    return image;\n                }\n            }\n            else\n            {\n                ProgramLogger.Exception($\"Unable to get logo for {UserModelId} from {path} and located in {Package.Location}\", new FileNotFoundException(), GetType(), path);\n                return new BitmapImage(new Uri(ImageLoader.ErrorIconPath));\n            }\n        }\n\n        public override string ToString()\n        {\n            return $\"{DisplayName}: {Description}\";\n        }\n    }\n\n    public enum LogoType\n    {\n        Error,\n        Colored,\n        HighContrast,\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"wox_plugin_program_run_as_administrator\" xml:space=\"preserve\">\n    <value>以管理员身份运行(Ctrl+Shift+Enter)</value>\n  </data>\n  <data name=\"wox_plugin_program_open_containing_folder\" xml:space=\"preserve\">\n    <value>打开所属文件夹(Ctrl+Shift+E)</value>\n  </data>\n  <data name=\"wox_plugin_program_open_in_console\" xml:space=\"preserve\">\n    <value>在命令行打开路径(Ctrl+Shift+C)</value>\n  </data>\n  <data name=\"wox_plugin_program_plugin_name\" xml:space=\"preserve\">\n    <value>应用程序</value>\n  </data>\n  <data name=\"wox_plugin_program_plugin_description\" xml:space=\"preserve\">\n    <value>搜索应用程序</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_win32_application\" xml:space=\"preserve\">\n    <value>Win32 应用</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_internet_shortcut_application\" xml:space=\"preserve\">\n    <value>网页快捷方式应用</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_web_application\" xml:space=\"preserve\">\n    <value>Web 应用</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_run_command\" xml:space=\"preserve\">\n    <value>命令行</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_packaged_application\" xml:space=\"preserve\">\n    <value>UWP 应用</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_file_name\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_file_path\" xml:space=\"preserve\">\n    <value>路径</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_folder_type\" xml:space=\"preserve\">\n    <value>文件夹</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_generic_file_type\" xml:space=\"preserve\">\n    <value>文件</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_start_failed\" xml:space=\"preserve\">\n    <value>无法启动</value>\n  </data>\n  <data name=\"powertoys_run_plugin_program_uwp_failed\" xml:space=\"preserve\">\n    <value>UWP 无法启动</value>\n  </data>\n  <data name=\"wox_plugin_program_run_as_user\" xml:space=\"preserve\">\n    <value>以其他用户身份运行(Ctrl+Shift+U)</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Main.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Globalization;\nusing System.IO;\nusing System.IO.Abstractions;\nusing System.Linq;\nusing System.Reflection;\nusing System.Text;\nusing System.Windows.Input;\n\nusing ManagedCommon;\nusing Microsoft.Plugin.Shell.Properties;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Wox.Infrastructure.Storage;\nusing Wox.Plugin;\nusing Wox.Plugin.Common;\nusing Wox.Plugin.Logger;\n\nusing Control = System.Windows.Controls.Control;\n\nnamespace Microsoft.Plugin.Shell\n{\n    public class Main : IPlugin, IPluginI18n, ISettingProvider, IContextMenu, ISavable\n    {\n        private static readonly IFileSystem FileSystem = new FileSystem();\n        private static readonly IPath Path = FileSystem.Path;\n        private static readonly IFile File = FileSystem.File;\n        private static readonly IDirectory Directory = FileSystem.Directory;\n\n        private readonly ShellPluginSettings _settings;\n        private readonly PluginJsonStorage<ShellPluginSettings> _storage;\n\n        private static readonly CompositeFormat WoxPluginCmdCmdHasBeenExecutedTimes = System.Text.CompositeFormat.Parse(Properties.Resources.wox_plugin_cmd_cmd_has_been_executed_times);\n\n        private string IconPath { get; set; }\n\n        public string Name => Properties.Resources.wox_plugin_cmd_plugin_name;\n\n        public string Description => Properties.Resources.wox_plugin_cmd_plugin_description;\n\n        public static string PluginID => \"D409510CD0D2481F853690A07E6DC426\";\n\n        public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()\n        {\n            new PluginAdditionalOption()\n            {\n                Key = \"ShellCommandExecution\",\n                DisplayLabel = Resources.wox_shell_command_execution,\n                DisplayDescription = Resources.wox_shell_command_execution_description,\n                PluginOptionType = PluginAdditionalOption.AdditionalOptionType.Combobox,\n                ComboBoxItems = new List<KeyValuePair<string, string>>\n                {\n                    new KeyValuePair<string, string>(Resources.find_executable_file_and_run_it, \"2\"),\n                    new KeyValuePair<string, string>(Resources.run_command_in_command_prompt, \"0\"),\n                    new KeyValuePair<string, string>(Resources.run_command_in_powershell, \"1\"),\n                    new KeyValuePair<string, string>(Resources.run_command_in_powershell_seven, \"6\"),\n                    new KeyValuePair<string, string>(Resources.run_command_in_windows_terminal_cmd, \"5\"),\n                    new KeyValuePair<string, string>(Resources.run_command_in_windows_terminal_powershell, \"3\"),\n                    new KeyValuePair<string, string>(Resources.run_command_in_windows_terminal_powershell_seven, \"4\"),\n                },\n                ComboBoxValue = (int)_settings.Shell,\n            },\n\n            new PluginAdditionalOption()\n            {\n                Key = \"LeaveShellOpen\",\n                DisplayLabel = Resources.wox_leave_shell_open,\n                Value = _settings.LeaveShellOpen,\n            },\n        };\n\n        private PluginInitContext _context;\n        private static readonly char[] Separator = new[] { ' ' };\n\n        public Main()\n        {\n            _storage = new PluginJsonStorage<ShellPluginSettings>();\n            _settings = _storage.Load();\n        }\n\n        public void Save()\n        {\n            _storage.Save();\n        }\n\n        public List<Result> Query(Query query)\n        {\n            ArgumentNullException.ThrowIfNull(query);\n\n            List<Result> results = new List<Result>();\n            string cmd = query.Search;\n            if (string.IsNullOrEmpty(cmd))\n            {\n                return ResultsFromlHistory();\n            }\n            else\n            {\n                var queryCmd = GetCurrentCmd(cmd);\n                results.Add(queryCmd);\n                var history = GetHistoryCmds(cmd, queryCmd);\n                results.AddRange(history);\n\n                try\n                {\n                    IEnumerable<Result> folderPluginResults = Folder.Main.GetFolderPluginResults(query);\n                    results.AddRange(folderPluginResults);\n                }\n                catch (Exception e)\n                {\n                    Log.Exception($\"Exception when query for <{query}>\", e, GetType());\n                }\n\n                return results;\n            }\n        }\n\n        private List<Result> GetHistoryCmds(string cmd, Result result)\n        {\n            IEnumerable<Result> history = _settings.Count.Where(o => o.Key.Contains(cmd, StringComparison.CurrentCultureIgnoreCase))\n                .OrderByDescending(o => o.Value)\n                .Select(m =>\n                {\n                    if (m.Key == cmd)\n                    {\n                        // Using CurrentCulture since this is user facing\n                        result.SubTitle = Properties.Resources.wox_plugin_cmd_plugin_name + \": \" + string.Format(CultureInfo.CurrentCulture, WoxPluginCmdCmdHasBeenExecutedTimes, m.Value);\n                        return null;\n                    }\n\n                    var ret = new Result\n                    {\n                        Title = m.Key,\n\n                        // Using CurrentCulture since this is user facing\n                        SubTitle = Properties.Resources.wox_plugin_cmd_plugin_name + \": \" + string.Format(CultureInfo.CurrentCulture, WoxPluginCmdCmdHasBeenExecutedTimes, m.Value),\n                        IcoPath = IconPath,\n                        Action = c =>\n                        {\n                            Execute(Process.Start, PrepareProcessStartInfo(m.Key));\n                            return true;\n                        },\n                    };\n                    return ret;\n                }).Where(o => o != null).Take(4);\n            return history.ToList();\n        }\n\n        private Result GetCurrentCmd(string cmd)\n        {\n            Result result = new Result\n            {\n                Title = cmd,\n                Score = 5000,\n                SubTitle = Properties.Resources.wox_plugin_cmd_plugin_name + \": \" + Properties.Resources.wox_plugin_cmd_execute_through_shell,\n                IcoPath = IconPath,\n                Action = c =>\n                {\n                    Execute(Process.Start, PrepareProcessStartInfo(cmd));\n                    return true;\n                },\n            };\n\n            return result;\n        }\n\n        private List<Result> ResultsFromlHistory()\n        {\n            IEnumerable<Result> history = _settings.Count.OrderByDescending(o => o.Value)\n                .Select(m => new Result\n                {\n                    Title = m.Key,\n\n                    // Using CurrentCulture since this is user facing\n                    SubTitle = Properties.Resources.wox_plugin_cmd_plugin_name + \": \" + string.Format(CultureInfo.CurrentCulture, WoxPluginCmdCmdHasBeenExecutedTimes, m.Value),\n                    IcoPath = IconPath,\n                    Action = c =>\n                    {\n                        Execute(Process.Start, PrepareProcessStartInfo(m.Key));\n                        return true;\n                    },\n                }).Take(5);\n            return history.ToList();\n        }\n\n        private ProcessStartInfo PrepareProcessStartInfo(string command, RunAsType runAs = RunAsType.None)\n        {\n            string trimmedCommand = command.Trim();\n            command = Environment.ExpandEnvironmentVariables(trimmedCommand);\n            var workingDirectory = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);\n\n            // Set runAsArg\n            string runAsVerbArg = string.Empty;\n            if (runAs == RunAsType.OtherUser)\n            {\n                runAsVerbArg = \"runAsUser\";\n            }\n            else if (runAs == RunAsType.Administrator || _settings.RunAsAdministrator)\n            {\n                runAsVerbArg = \"runAs\";\n            }\n\n            ProcessStartInfo info;\n            if (_settings.Shell == ExecutionShell.Cmd)\n            {\n                var arguments = _settings.LeaveShellOpen ? $\"/k \\\"{command}\\\"\" : $\"/c \\\"{command}\\\" & pause\";\n\n                info = ShellCommand.SetProcessStartInfo(\"cmd.exe\", workingDirectory, arguments, runAsVerbArg);\n            }\n            else if (_settings.Shell == ExecutionShell.Powershell)\n            {\n                string arguments;\n                if (_settings.LeaveShellOpen)\n                {\n                    arguments = $\"-NoExit \\\"{command}\\\"\";\n                }\n                else\n                {\n                    arguments = $\"\\\"{command} ; Read-Host -Prompt \\\\\\\"{Resources.run_plugin_cmd_wait_message}\\\\\\\"\\\"\";\n                }\n\n                info = ShellCommand.SetProcessStartInfo(\"powershell.exe\", workingDirectory, arguments, runAsVerbArg);\n            }\n            else if (_settings.Shell == ExecutionShell.PowerShellSeven)\n            {\n                string arguments;\n                if (_settings.LeaveShellOpen)\n                {\n                    arguments = $\"-NoExit -C \\\"{command}\\\"\";\n                }\n                else\n                {\n                    arguments = $\"-C \\\"{command} ; Read-Host -Prompt \\\\\\\"{Resources.run_plugin_cmd_wait_message}\\\\\\\"\\\"\";\n                }\n\n                info = ShellCommand.SetProcessStartInfo(\"pwsh.exe\", workingDirectory, arguments, runAsVerbArg);\n            }\n            else if (_settings.Shell == ExecutionShell.WindowsTerminalCmd)\n            {\n                string arguments;\n                if (_settings.LeaveShellOpen)\n                {\n                    arguments = $\"cmd.exe /k \\\"{command}\\\"\";\n                }\n                else\n                {\n                    arguments = $\"cmd.exe /c \\\"{command}\\\" & pause\";\n                }\n\n                info = ShellCommand.SetProcessStartInfo(\"wt.exe\", workingDirectory, arguments, runAsVerbArg);\n            }\n            else if (_settings.Shell == ExecutionShell.WindowsTerminalPowerShell)\n            {\n                string arguments;\n                if (_settings.LeaveShellOpen)\n                {\n                    arguments = $\"powershell -NoExit -C \\\"{command}\\\"\";\n                }\n                else\n                {\n                    arguments = $\"powershell -C \\\"{command}\\\"\";\n                }\n\n                info = ShellCommand.SetProcessStartInfo(\"wt.exe\", workingDirectory, arguments, runAsVerbArg);\n            }\n            else if (_settings.Shell == ExecutionShell.WindowsTerminalPowerShellSeven)\n            {\n                string arguments;\n                if (_settings.LeaveShellOpen)\n                {\n                    arguments = $\"pwsh.exe -NoExit -C \\\"{command}\\\"\";\n                }\n                else\n                {\n                    arguments = $\"pwsh.exe -C \\\"{command}\\\"\";\n                }\n\n                info = ShellCommand.SetProcessStartInfo(\"wt.exe\", workingDirectory, arguments, runAsVerbArg);\n            }\n            else if (_settings.Shell == ExecutionShell.RunCommand)\n            {\n                // Open explorer if the path is a file or directory\n                if (Directory.Exists(command) || File.Exists(command))\n                {\n                    info = ShellCommand.SetProcessStartInfo(\"explorer.exe\", arguments: command, verb: runAsVerbArg);\n                }\n                else\n                {\n                    var parts = command.Split(Separator, 2);\n                    if (parts.Length == 2)\n                    {\n                        var filename = parts[0];\n                        if (ExistInPath(filename))\n                        {\n                            var arguments = parts[1];\n                            if (_settings.LeaveShellOpen)\n                            {\n                                // Wrap the command in a cmd.exe process\n                                info = ShellCommand.SetProcessStartInfo(\"cmd.exe\", workingDirectory, $\"/k \\\"{filename} {arguments}\\\"\", runAsVerbArg);\n                            }\n                            else\n                            {\n                                info = ShellCommand.SetProcessStartInfo(filename, workingDirectory, arguments, runAsVerbArg);\n                            }\n                        }\n                        else\n                        {\n                            if (_settings.LeaveShellOpen)\n                            {\n                                // Wrap the command in a cmd.exe process\n                                info = ShellCommand.SetProcessStartInfo(\"cmd.exe\", workingDirectory, $\"/k \\\"{command}\\\"\", runAsVerbArg);\n                            }\n                            else\n                            {\n                                info = ShellCommand.SetProcessStartInfo(command, verb: runAsVerbArg);\n                            }\n                        }\n                    }\n                    else\n                    {\n                        if (_settings.LeaveShellOpen)\n                        {\n                            // Wrap the command in a cmd.exe process\n                            info = ShellCommand.SetProcessStartInfo(\"cmd.exe\", workingDirectory, $\"/k \\\"{command}\\\"\", runAsVerbArg);\n                        }\n                        else\n                        {\n                            info = ShellCommand.SetProcessStartInfo(command, verb: runAsVerbArg);\n                        }\n                    }\n                }\n            }\n            else\n            {\n                throw new NotImplementedException();\n            }\n\n            info.UseShellExecute = true;\n\n            _settings.AddCmdHistory(trimmedCommand);\n\n            return info;\n        }\n\n        private enum RunAsType\n        {\n            None,\n            Administrator,\n            OtherUser,\n        }\n\n        private void Execute(Func<ProcessStartInfo, Process> startProcess, ProcessStartInfo info)\n        {\n            try\n            {\n                startProcess(info);\n            }\n            catch (FileNotFoundException e)\n            {\n                var name = \"插件: \" + Properties.Resources.wox_plugin_cmd_plugin_name;\n                var message = $\"{Properties.Resources.wox_plugin_cmd_command_not_found}: {e.Message}\";\n                _context.API.ShowMsg(name, message);\n            }\n            catch (Win32Exception e)\n            {\n                var name = \"插件: \" + Properties.Resources.wox_plugin_cmd_plugin_name;\n                var message = $\"{Properties.Resources.wox_plugin_cmd_command_failed}: {e.Message}\";\n                _context.API.ShowMsg(name, message);\n            }\n        }\n\n        private static bool ExistInPath(string filename)\n        {\n            if (File.Exists(filename))\n            {\n                return true;\n            }\n            else\n            {\n                var values = Environment.GetEnvironmentVariable(\"PATH\");\n                if (values != null)\n                {\n                    foreach (var path in values.Split(';'))\n                    {\n                        var path1 = Path.Combine(path, filename);\n                        var path2 = Path.Combine(path, filename + \".exe\");\n                        if (File.Exists(path1) || File.Exists(path2))\n                        {\n                            return true;\n                        }\n                    }\n\n                    return false;\n                }\n                else\n                {\n                    return false;\n                }\n            }\n        }\n\n        public void Init(PluginInitContext context)\n        {\n            this._context = context;\n            _context.API.ThemeChanged += OnThemeChanged;\n            UpdateIconPath(_context.API.GetCurrentTheme());\n        }\n\n        // Todo : Update with theme based IconPath\n        private void UpdateIconPath(Theme theme)\n        {\n            if (theme == Theme.Light || theme == Theme.HighContrastWhite)\n            {\n                IconPath = \"Images/shell.light.png\";\n            }\n            else\n            {\n                IconPath = \"Images/shell.dark.png\";\n            }\n        }\n\n        private void OnThemeChanged(Theme currentTheme, Theme newTheme)\n        {\n            UpdateIconPath(newTheme);\n        }\n\n        public Control CreateSettingPanel()\n        {\n            throw new NotImplementedException();\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Properties.Resources.wox_plugin_cmd_plugin_name;\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Properties.Resources.wox_plugin_cmd_plugin_description;\n        }\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            var resultlist = new List<ContextMenuResult>\n            {\n                new ContextMenuResult\n                {\n                    PluginName = Assembly.GetExecutingAssembly().GetName().Name,\n                    Title = Properties.Resources.wox_plugin_cmd_run_as_administrator,\n                    Glyph = \"\\xE7EF\",\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    AcceleratorKey = Key.Enter,\n                    AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                    Action = c =>\n                    {\n                        Execute(Process.Start, PrepareProcessStartInfo(selectedResult.Title, RunAsType.Administrator));\n                        return true;\n                    },\n                },\n                new ContextMenuResult\n                {\n                    PluginName = Assembly.GetExecutingAssembly().GetName().Name,\n                    Title = Properties.Resources.wox_plugin_cmd_run_as_user,\n                    Glyph = \"\\xE7EE\",\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    AcceleratorKey = Key.U,\n                    AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                    Action = _ =>\n                    {\n                        Execute(Process.Start, PrepareProcessStartInfo(selectedResult.Title, RunAsType.OtherUser));\n                        return true;\n                    },\n                },\n            };\n\n            return resultlist;\n        }\n\n        public void UpdateSettings(PowerLauncherPluginSettings settings)\n        {\n            var leaveShellOpen = false;\n            var shellOption = 2;\n\n            if (settings != null && settings.AdditionalOptions != null)\n            {\n                var optionLeaveShellOpen = settings.AdditionalOptions.FirstOrDefault(x => x.Key == \"LeaveShellOpen\");\n                leaveShellOpen = optionLeaveShellOpen?.Value ?? leaveShellOpen;\n                _settings.LeaveShellOpen = leaveShellOpen;\n\n                var optionShell = settings.AdditionalOptions.FirstOrDefault(x => x.Key == \"ShellCommandExecution\");\n                shellOption = optionShell?.ComboBoxValue ?? shellOption;\n                _settings.Shell = (ExecutionShell)shellOption;\n            }\n\n            Save();\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Shell/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"wox_plugin_cmd_plugin_name\" xml:space=\"preserve\">\n    <value>命令行</value>\n  </data>\n  <data name=\"wox_plugin_cmd_plugin_description\" xml:space=\"preserve\">\n    <value>执行命令（例如 “ping”、“cmd”）</value>\n  </data>\n  <data name=\"wox_plugin_cmd_cmd_has_been_executed_times\" xml:space=\"preserve\">\n    <value>此命令已经执行了 {0} 次</value>\n  </data>\n  <data name=\"wox_plugin_cmd_execute_through_shell\" xml:space=\"preserve\">\n    <value>执行此命令</value>\n  </data>\n  <data name=\"wox_plugin_cmd_run_as_administrator\" xml:space=\"preserve\">\n    <value>以管理员身份打开/执行(Ctrl+Shift+Enter)</value>\n  </data>\n  <data name=\"wox_plugin_cmd_command_failed\" xml:space=\"preserve\">\n    <value>命令执行错误</value>\n  </data>\n  <data name=\"wox_plugin_cmd_command_not_found\" xml:space=\"preserve\">\n    <value>命令不存在</value>\n  </data>\n  <data name=\"wox_plugin_cmd_run_as_user\" xml:space=\"preserve\">\n    <value>以管理员身份打开/执行(Ctrl+Shift+U)</value>\n  </data>\n  <data name=\"wox_leave_shell_open\" xml:space=\"preserve\">\n    <value>保持终端窗口打开</value>\n  </data>\n  <data name=\"wox_shell_command_execution\" xml:space=\"preserve\">\n    <value>命令执行方式</value>\n  </data>\n  <data name=\"run_command_in_command_prompt\" xml:space=\"preserve\">\n    <value>命令提示符 (cmd.exe)</value>\n  </data>\n  <data name=\"run_command_in_powershell\" xml:space=\"preserve\">\n    <value>PowerShell (PowerShell.exe)</value>\n  </data>\n  <data name=\"find_executable_file_and_run_it\" xml:space=\"preserve\">\n    <value>寻找并执行可执行文件</value>\n  </data>\n  <data name=\"run_command_in_powershell_seven\" xml:space=\"preserve\">\n    <value>PowerShell 7 (pwsh.exe)</value>\n  </data>\n  <data name=\"run_command_in_windows_terminal_cmd\" xml:space=\"preserve\">\n    <value>终端中打开命令提示符 (cmd.exe)</value>\n  </data>\n  <data name=\"run_command_in_windows_terminal_powershell\" xml:space=\"preserve\">\n    <value>终端中打开 PowerShell (PowerShell.exe)</value>\n  </data>\n  <data name=\"run_command_in_windows_terminal_powershell_seven\" xml:space=\"preserve\">\n    <value>终端中打开 PowerShell 7 (pwsh.exe)</value>\n  </data>\n  <data name=\"run_plugin_cmd_wait_message\" xml:space=\"preserve\">\n    <value>按下 Enter 继续</value>\n    <comment>\"Enter\" means the Enter key on the keyboard.</comment>\n  </data>\n  <data name=\"wox_shell_command_execution_description\" xml:space=\"preserve\">\n    <value>指定使用 Windows 终端来执行就会忽略默认终端应用程序设置</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Main.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\n\nusing ManagedCommon;\nusing Microsoft.Plugin.Uri.UriHelper;\nusing Wox.Infrastructure;\nusing Wox.Infrastructure.Storage;\nusing Wox.Plugin;\n\nusing BrowserInfo = Wox.Plugin.Common.DefaultBrowserInfo;\n\nnamespace Microsoft.Plugin.Uri\n{\n    public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable, IDisposable\n    {\n        private readonly ExtendedUriParser _uriParser;\n        private readonly UriResolver _uriResolver;\n        private readonly PluginJsonStorage<UriSettings> _storage;\n        private bool _disposed;\n        private UriSettings _uriSettings;\n\n        public Main()\n        {\n            _storage = new PluginJsonStorage<UriSettings>();\n            _uriSettings = _storage.Load();\n            _uriParser = new ExtendedUriParser();\n            _uriResolver = new UriResolver();\n        }\n\n        public string DefaultIconPath { get; set; }\n\n        public PluginInitContext Context { get; protected set; }\n\n        public string Name => Properties.Resources.Microsoft_plugin_uri_plugin_name;\n\n        public string Description => Properties.Resources.Microsoft_plugin_uri_plugin_description;\n\n        public static string PluginID => \"03276A39D4E9417C8FFD200B0EE5E871\";\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            return new List<ContextMenuResult>(0);\n        }\n\n        public List<Result> Query(Query query)\n        {\n            var results = new List<Result>();\n\n            if (string.IsNullOrWhiteSpace(query?.Search) && BrowserInfo.IsDefaultBrowserSet)\n            {\n                results.Add(new Result\n                {\n                    Title = Properties.Resources.Microsoft_plugin_uri_default_browser,\n                    SubTitle = BrowserInfo.Path,\n                    IcoPath = DefaultIconPath,\n                    Action = action =>\n                    {\n                        if (!Helper.OpenInShell(BrowserInfo.Path))\n                        {\n                            var title = $\"插件: {Properties.Resources.Microsoft_plugin_uri_plugin_name}\";\n                            var message = $\"{Properties.Resources.Microsoft_plugin_uri_open_failed}: \";\n                            Context.API.ShowMsg(title, message);\n                            return false;\n                        }\n\n                        return true;\n                    },\n                });\n                return results;\n            }\n\n            if (!string.IsNullOrEmpty(query?.Search)\n                && _uriParser.TryParse(query.Search, out var webUriResult, out var systemUriResult)\n                && _uriResolver.IsValidHost(webUriResult))\n            {\n                if (webUriResult is not null)\n                {\n                    var resultString = webUriResult.ToString();\n                    results.Add(new Result\n                    {\n                        Title = resultString,\n                        SubTitle = Properties.Resources.Microsoft_plugin_uri_website,\n                        IcoPath = BrowserInfo.IconPath,\n                        Action = action =>\n                        {\n                            if (!Helper.OpenInShell(resultString))\n                            {\n                                var title = $\"插件: {Properties.Resources.Microsoft_plugin_uri_plugin_name}\";\n                                var message = $\"{Properties.Resources.Microsoft_plugin_uri_open_failed}: {resultString}\";\n                                Context.API.ShowMsg(title, message);\n                                return false;\n                            }\n\n                            return true;\n                        },\n                    });\n                }\n\n                if (systemUriResult is not null)\n                {\n                    var resultString = systemUriResult.ToString();\n                    results.Add(new Result\n                    {\n                        Title = resultString,\n                        SubTitle = Properties.Resources.Microsoft_plugin_uri_open,\n                        IcoPath = DefaultIconPath,\n                        Action = action =>\n                        {\n                            if (!Helper.OpenInShell(resultString))\n                            {\n                                var title = $\"插件: {Properties.Resources.Microsoft_plugin_uri_plugin_name}\";\n                                var message = $\"{Properties.Resources.Microsoft_plugin_uri_open_failed}: {resultString}\";\n                                Context.API.ShowMsg(title, message);\n                                return false;\n                            }\n\n                            return true;\n                        },\n                    });\n                }\n            }\n\n            return results;\n        }\n\n        public void Init(PluginInitContext context)\n        {\n            Context = context ?? throw new ArgumentNullException(nameof(context));\n            Context.API.ThemeChanged += OnThemeChanged;\n            UpdateIconPath(Context.API.GetCurrentTheme());\n            BrowserInfo.UpdateIfTimePassed();\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Properties.Resources.Microsoft_plugin_uri_plugin_name;\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Properties.Resources.Microsoft_plugin_uri_plugin_description;\n        }\n\n        public void Save()\n        {\n            _storage.Save();\n        }\n\n        private void OnThemeChanged(Theme oldtheme, Theme newTheme)\n        {\n            UpdateIconPath(newTheme);\n        }\n\n        private void UpdateIconPath(Theme theme)\n        {\n            if (theme == Theme.Light || theme == Theme.HighContrastWhite)\n            {\n                DefaultIconPath = \"Images/uri.light.png\";\n            }\n            else\n            {\n                DefaultIconPath = \"Images/uri.dark.png\";\n            }\n        }\n\n        public void ReloadData()\n        {\n            if (Context is null)\n            {\n                return;\n            }\n\n            BrowserInfo.UpdateIfTimePassed();\n        }\n\n        public void Dispose()\n        {\n            Dispose(true);\n            GC.SuppressFinalize(this);\n        }\n\n        protected virtual void Dispose(bool disposing)\n        {\n            if (!_disposed && disposing)\n            {\n                if (Context != null && Context.API != null)\n                {\n                    Context.API.ThemeChanged -= OnThemeChanged;\n                }\n\n                _disposed = true;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.Uri/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Microsoft_plugin_default_browser_open_failed\" xml:space=\"preserve\">\n    <value>无法打开默认浏览器</value>\n  </data>\n  <data name=\"Microsoft_plugin_uri_default_browser\" xml:space=\"preserve\">\n    <value>打开默认浏览器</value>\n  </data>\n  <data name=\"Microsoft_plugin_uri_open\" xml:space=\"preserve\">\n    <value>打开网址</value>\n  </data>\n  <data name=\"Microsoft_plugin_uri_open_failed\" xml:space=\"preserve\">\n    <value>无法打开网址</value>\n  </data>\n  <data name=\"Microsoft_plugin_uri_plugin_description\" xml:space=\"preserve\">\n    <value>打开网址和 UNC 网络共享</value>\n  </data>\n  <data name=\"Microsoft_plugin_uri_plugin_name\" xml:space=\"preserve\">\n    <value>网址</value>\n  </data>\n  <data name=\"Microsoft_plugin_uri_website\" xml:space=\"preserve\">\n    <value>在浏览器中打开</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.Plugin.WindowWalker/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"wox_plugin_windowwalker_plugin_name\" xml:space=\"preserve\">\n    <value>窗口操作</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_plugin_description\" xml:space=\"preserve\">\n    <value>通过搜索窗口标题来操作窗口</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_Running\" xml:space=\"preserve\">\n    <value>进程</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingConfirmKillProcess\" xml:space=\"preserve\">\n    <value>结束进程时弹窗确认</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingExplorerSettingInfo\" xml:space=\"preserve\">\n    <value>隐藏资源管理器进程</value>\n    <comment>Explorer is here the program File Explorer</comment>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingHideKillProcess\" xml:space=\"preserve\">\n    <value>需要管理员权限才能结束进程时，隐藏“结束进程”按钮</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingResultsVisibleDesktop\" xml:space=\"preserve\">\n    <value>仅显示在桌面可见的进程</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingSubtitleDesktopName\" xml:space=\"preserve\">\n    <value>在结果中显示进程所在的虚拟桌面</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingSubtitlePid\" xml:space=\"preserve\">\n    <value>在结果中显示进程 ID</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingOpenAfterKillAndClose\" xml:space=\"preserve\">\n    <value>使用操作后不关闭启动器</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_Desktop\" xml:space=\"preserve\">\n    <value>虚拟桌面</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_Number\" xml:space=\"preserve\">\n    <value>No.</value>\n    <comment>Short version of \"Number\"</comment>\n  </data>\n  <data name=\"wox_plugin_windowwalker_Process\" xml:space=\"preserve\">\n    <value>进程名称</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_ProcessId\" xml:space=\"preserve\">\n    <value>进程 ID </value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_ExplorerInfoSubTitle\" xml:space=\"preserve\">\n    <value>文件夹窗口需要是独立的进程，点击修改资源管理器设置</value>\n    <comment>Explorer is here the program File Explorer</comment>\n  </data>\n  <data name=\"wox_plugin_windowwalker_ExplorerInfoTitle\" xml:space=\"preserve\">\n    <value>提示：无法结束资源管理器进程</value>\n    <comment>Explorer is here the program File Explorer</comment>\n  </data>\n  <data name=\"wox_plugin_windowwalker_Close\" xml:space=\"preserve\">\n    <value>关闭窗口</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_Kill\" xml:space=\"preserve\">\n    <value>结束进程</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_KillMessage\" xml:space=\"preserve\">\n    <value>你即将结束以下进程:</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_KillMessageQuestion\" xml:space=\"preserve\">\n    <value>确定执行?</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_KillMessageTitle\" xml:space=\"preserve\">\n    <value>结束进程确认</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_KillMessageUwp\" xml:space=\"preserve\">\n    <value>由于这是一个 UWP 进程，所有的实例都将被结束。确定执行?</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingKillProcessTree\" xml:space=\"preserve\">\n    <value>结束进程，同时结束其子进程</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingExplorerSettingInfo_Description\" xml:space=\"preserve\">\n    <value>其仅在使用唤醒词进行搜索时显示</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingKillProcessTree_Description\" xml:space=\"preserve\">\n    <value>使用该功能须谨慎，结束整个进程树可能导致特定应用程序崩溃</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingOpenAfterKillAndClose_Description\" xml:space=\"preserve\">\n    <value>如果启用了弹窗确认，则此功能无法生效</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_SettingSubtitleDesktopName_Description\" xml:space=\"preserve\">\n    <value>若有多个虚拟桌面，程序在哪个虚拟桌面的信息</value>\n  </data>\n  <data name=\"wox_plugin_windowwalker_NotResponding\" xml:space=\"preserve\">\n    <value>无响应</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Calculator/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"wox_plugin_calculator_plugin_name\" xml:space=\"preserve\">\n    <value>计算器</value>\n  </data>\n  <data name=\"wox_plugin_calculator_plugin_description\" xml:space=\"preserve\">\n    <value>进行数学计算，例如 5*3-2</value>\n  </data>\n  <data name=\"wox_plugin_calculator_not_a_number\" xml:space=\"preserve\">\n    <value>发生 NaN 错误，结果不是数字</value>\n  </data>\n  <data name=\"wox_plugin_calculator_expression_not_complete\" xml:space=\"preserve\">\n    <value>表达式错误或不完整，可能缺少括号</value>\n  </data>\n  <data name=\"wox_plugin_calculator_copy_number_to_clipboard\" xml:space=\"preserve\">\n    <value>复制计算结果</value>\n  </data>\n  <data name=\"wox_plugin_calculator_copy_failed\" xml:space=\"preserve\">\n    <value>复制失败，请稍后再试</value>\n  </data>\n  <data name=\"wox_plugin_calculator_calculation_failed\" xml:space=\"preserve\">\n    <value>计算错误</value>\n  </data>\n  <data name=\"wox_plugin_calculator_double_array_returned\" xml:space=\"preserve\">\n    <value>暂不支持使用方括号</value>\n  </data>\n  <data name=\"wox_plugin_calculator_not_covert_to_decimal\" xml:space=\"preserve\">\n    <value>结果超过十进制数字范围</value>\n  </data>\n  <data name=\"wox_plugin_calculator_in_en_format\" xml:space=\"preserve\">\n    <value>输入英语格式数字</value>\n  </data>\n  <data name=\"wox_plugin_calculator_in_en_format_description\" xml:space=\"preserve\">\n    <value>强制输入英语格式的数字，例如 '{0}'</value>\n    <comment>{0} is a placeholder and will be replaced in code.</comment>\n  </data>\n  <data name=\"wox_plugin_calculator_out_en_format\" xml:space=\"preserve\">\n    <value>输出英语格式数字</value>\n  </data>\n  <data name=\"wox_plugin_calculator_out_en_format_description\" xml:space=\"preserve\">\n    <value>强制输出英语格式的数字，例如 '{0}'</value>\n    <comment>{0} is a placeholder and will be replaced in code.</comment>\n  </data>\n  <data name=\"wox_plugin_calculator_division_by_zero\" xml:space=\"preserve\">\n    <value>零不可以作为除数</value>\n  </data>\n  <data name=\"wox_plugin_calculator_replace_input\" xml:space=\"preserve\">\n    <value>式子以等号结尾时，自动填入运算结果</value>\n  </data>\n  <data name=\"wox_plugin_calculator_replace_input_description\" xml:space=\"preserve\">\n    <value>使用唤醒词激活时，在式子后输入 \"=\" 就用运算结果替换整个式子（例如输入 '=5*3-2=' 就会变成 '=13'）</value>\n  </data>\n  <data name=\"wox_plugin_calculator_trig_unit_mode\" xml:space=\"preserve\">\n    <value>三角函数单位</value>\n    <comment>Title text for trig unit mode.</comment>\n  </data>\n  <data name=\"wox_plugin_calculator_trig_unit_mode_description\" xml:space=\"preserve\">\n    <value>指定三角函数运算使用的角度单位制</value>\n    <comment>Description text for trig mode setting.</comment>\n  </data>\n  <data name=\"wox_plugin_calculator_trig_unit_radians\" xml:space=\"preserve\">\n    <value>弧度（圆=2π）</value>\n    <comment>Text for angle unit.</comment>\n  </data>\n  <data name=\"wox_plugin_calculator_trig_unit_degrees\" xml:space=\"preserve\">\n    <value>角度（圆=360）</value>\n    <comment>Text to use for angle unit.</comment>\n  </data>\n  <data name=\"wox_plugin_calculator_trig_unit_gradians\" xml:space=\"preserve\">\n    <value>梯度（圆=400）</value>\n    <comment>Text for angle unit.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.History/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"wox_plugin_history_plugin_name\" xml:space=\"preserve\">\n    <value>历史记录</value>\n  </data>\n  <data name=\"wox_plugin_history_plugin_description\" xml:space=\"preserve\">\n    <value>访问启动器的搜索记录</value>\n  </data>\n  <data name=\"wox_plugin_history_processing_failed\" xml:space=\"preserve\">\n    <value>无法处理该输入</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.OneNote/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"PluginTitle\" xml:space=\"preserve\">\n    <value>OneNote 笔记</value>\n  </data>\n  <data name=\"PluginDescription\" xml:space=\"preserve\">\n    <value>搜索 OneNone 桌面版中的笔记</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.PowerToys/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Action_Open_Settings\" xml:space=\"preserve\">\n    <value>打开设置 (Ctrl+Shift+S)</value>\n  </data>\n  <data name=\"Action_Run_As_Administrator\" xml:space=\"preserve\">\n    <value>管理员权限运行 (Ctrl+Shift+Enter)</value>\n  </data>\n  <data name=\"Color_Picker\" xml:space=\"preserve\">\n    <value>取色器</value>\n    <comment>\"Color Picker\" is the name of the utility</comment>\n  </data>\n  <data name=\"Crop_And_Lock_Reparent\" xml:space=\"preserve\">\n    <value>窗口镜像（重定向）</value>\n    <comment>\"Crop And Lock\" is the name of the utility, \"Reparent\" is the activation mode</comment>\n  </data>\n  <data name=\"Crop_And_Lock_Thumbnail\" xml:space=\"preserve\">\n    <value>窗口镜像（投影）</value>\n    <comment>\"Crop And Lock\" is the name of the utility, \"Thumbnail\" is the activation mode</comment>\n  </data>\n  <data name=\"Environment_Variables\" xml:space=\"preserve\">\n    <value>环境变量编辑器</value>\n    <comment>\"Environment Variables\" is the name of the utility</comment>\n  </data>\n  <data name=\"Workspaces_Editor\" xml:space=\"preserve\">\n    <value>工作区编辑器</value>\n    <comment>\"Workspaces\" is the name of the utility</comment>\n  </data>\n  <data name=\"FancyZones_Editor\" xml:space=\"preserve\">\n    <value>窗口布局编辑器</value>\n    <comment>\"FancyZones\" is the name of the utility</comment>\n  </data>\n  <data name=\"Hosts_File_Editor\" xml:space=\"preserve\">\n    <value>域名表编辑器</value>\n    <comment>\"Hosts File Editor\" is the name of the utility</comment>\n  </data>\n  <data name=\"Plugin_Description\" xml:space=\"preserve\">\n    <value>打开 PowerToys 功能</value>\n  </data>\n  <data name=\"Plugin_Name\" xml:space=\"preserve\">\n    <value>PowerToys</value>\n  </data>\n  <data name=\"Registry_Preview\" xml:space=\"preserve\">\n    <value>注册表预览工具</value>\n    <comment>\"Registry Preview\" is the name of the utility</comment>\n  </data>\n  <data name=\"Screen_Ruler\" xml:space=\"preserve\">\n    <value>屏幕标尺</value>\n    <comment>\"Screen Ruler\" is the name of the utility</comment>\n  </data>\n  <data name=\"Shortcut_Guide\" xml:space=\"preserve\">\n    <value>快捷键指南</value>\n    <comment>\"Shortcut Guide\" is the name of the utility</comment>\n  </data>\n  <data name=\"Subtitle_Powertoys_Utility\" xml:space=\"preserve\">\n    <value>PowerToys 功能</value>\n  </data>\n  <data name=\"Text_Extractor\" xml:space=\"preserve\">\n    <value>文本提取器</value>\n    <comment>\"Text Extractor\" is the name of the utility</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Registry/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"PluginTitle\" xml:space=\"preserve\">\n    <value>注册表</value>\n  </data>\n  <data name=\"PluginDescription\" xml:space=\"preserve\">\n    <value>浏览 Windows 注册表</value>\n    <comment>\"this built into Windows the OS. translate accordingly, https://learn.microsoft.com/troubleshoot/windows-server/performance/windows-registry-advanced-users is an example of it translated in German\"</comment>\n  </data>\n  <data name=\"CopyKeyNamePath\" xml:space=\"preserve\">\n    <value>复制路径</value>\n    <comment>'The maximum size of a key name is 255 characters.'</comment>\n  </data>\n  <data name=\"KeyName\" xml:space=\"preserve\">\n    <value>路径:</value>\n    <comment>'The maximum size of a key name is 255 characters.'</comment>\n  </data>\n  <data name=\"Name\" xml:space=\"preserve\">\n    <value>名称:</value>\n  </data>\n  <data name=\"CopyValueName\" xml:space=\"preserve\">\n    <value>复制值名称</value>\n  </data>\n  <data name=\"OpenKeyInRegistryEditor\" xml:space=\"preserve\">\n    <value>在注册表编辑器中打开</value>\n    <comment>\"registry editor\" is the name of the OS built-in application</comment>\n  </data>\n  <data name=\"OpenInRegistryEditorAccessExceptionText\" xml:space=\"preserve\">\n    <value>没有权限打开 Windows 注册表编辑器</value>\n    <comment>\"registry editor\" is the name of the OS built-in application </comment>\n  </data>\n  <data name=\"OpenInRegistryEditorAccessExceptionTitle\" xml:space=\"preserve\">\n    <value>注册表编辑器打开失败</value>\n    <comment>\"registry editor\" is the name of the OS built-in application</comment>\n  </data>\n  <data name=\"SubKeys\" xml:space=\"preserve\">\n    <value>子项:</value>\n  </data>\n  <data name=\"Values\" xml:space=\"preserve\">\n    <value>值:</value>\n  </data>\n  <data name=\"RegistryKey\" xml:space=\"preserve\">\n    <value>注册表项</value>\n  </data>\n  <data name=\"RegistryValue\" xml:space=\"preserve\">\n    <value>注册表值</value>\n  </data>\n  <data name=\"Type\" xml:space=\"preserve\">\n    <value>类型:</value>\n    <comment>See https://learn.microsoft.com/windows/win32/sysinfo/registry-value-types for proper context of how to translate 'type'</comment>\n  </data>\n  <data name=\"Value\" xml:space=\"preserve\">\n    <value>数据:</value>\n    <comment>See https://learn.microsoft.com/windows/win32/sysinfo/registry-value-types for proper context of how to translate 'value'</comment>\n  </data>\n  <data name=\"RegistryValueKindNone\" xml:space=\"preserve\">\n    <value>无类型</value>\n  </data>\n  <data name=\"RegistryValueKindUnknown\" xml:space=\"preserve\">\n    <value>未知类型</value>\n  </data>\n  <data name=\"CopyValueData\" xml:space=\"preserve\">\n    <value>复制值数据</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.Service/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"wox_plugin_service_continue_pending\" xml:space=\"preserve\">\n    <value>正在恢复</value>\n  </data>\n  <data name=\"wox_plugin_service_name\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"wox_plugin_service_open_services\" xml:space=\"preserve\">\n    <value>管理服务(Ctrl+O)</value>\n  </data>\n  <data name=\"wox_plugin_service_paused\" xml:space=\"preserve\">\n    <value>已暂停</value>\n  </data>\n  <data name=\"wox_plugin_service_pause_pending\" xml:space=\"preserve\">\n    <value>正在暂停</value>\n  </data>\n  <data name=\"wox_plugin_service_plugin_description\" xml:space=\"preserve\">\n    <value>管理 Windows 服务</value>\n  </data>\n  <data name=\"wox_plugin_service_plugin_name\" xml:space=\"preserve\">\n    <value>服务</value>\n  </data>\n  <data name=\"wox_plugin_service_restart\" xml:space=\"preserve\">\n    <value>重启(Ctrl+R)</value>\n  </data>\n  <data name=\"wox_plugin_service_restarted_notification\" xml:space=\"preserve\">\n    <value>服务已重新启动</value>\n  </data>\n  <data name=\"wox_plugin_service_restart_error_notification\" xml:space=\"preserve\">\n    <value>重启服务时出错</value>\n  </data>\n  <data name=\"wox_plugin_service_running\" xml:space=\"preserve\">\n    <value>正在运行</value>\n  </data>\n  <data name=\"wox_plugin_service_start\" xml:space=\"preserve\">\n    <value>启动(Enter)</value>\n  </data>\n  <data name=\"wox_plugin_service_started\" xml:space=\"preserve\">\n    <value>已启动</value>\n  </data>\n  <data name=\"wox_plugin_service_started_notification\" xml:space=\"preserve\">\n    <value>服务已启动</value>\n  </data>\n  <data name=\"wox_plugin_service_startup\" xml:space=\"preserve\">\n    <value>启动类型</value>\n  </data>\n  <data name=\"wox_plugin_service_start_error_notification\" xml:space=\"preserve\">\n    <value>启动服务时出错</value>\n  </data>\n  <data name=\"wox_plugin_service_start_mode_automatic\" xml:space=\"preserve\">\n    <value>自动</value>\n  </data>\n  <data name=\"wox_plugin_service_start_mode_automaticDelayed\" xml:space=\"preserve\">\n    <value>自动(延迟启动)</value>\n  </data>\n  <data name=\"wox_plugin_service_start_mode_boot\" xml:space=\"preserve\">\n    <value>开机启动</value>\n  </data>\n  <data name=\"wox_plugin_service_start_mode_disabled\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"wox_plugin_service_start_mode_manual\" xml:space=\"preserve\">\n    <value>手动</value>\n  </data>\n  <data name=\"wox_plugin_service_start_mode_system\" xml:space=\"preserve\">\n    <value>系统</value>\n  </data>\n  <data name=\"wox_plugin_service_start_pending\" xml:space=\"preserve\">\n    <value>正在启动</value>\n  </data>\n  <data name=\"wox_plugin_service_status\" xml:space=\"preserve\">\n    <value>状态</value>\n  </data>\n  <data name=\"wox_plugin_service_stop\" xml:space=\"preserve\">\n    <value>停止(Enter)</value>\n  </data>\n  <data name=\"wox_plugin_service_stopped\" xml:space=\"preserve\">\n    <value>已停止</value>\n  </data>\n  <data name=\"wox_plugin_service_stopped_notification\" xml:space=\"preserve\">\n    <value>服务已停止</value>\n  </data>\n  <data name=\"wox_plugin_service_stop_error_notification\" xml:space=\"preserve\">\n    <value>停止服务时出错</value>\n  </data>\n  <data name=\"wox_plugin_service_stop_pending\" xml:space=\"preserve\">\n    <value>正在停止</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Components/ResultHelper.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Input;\n\nusing Microsoft.PowerToys.Run.Plugin.System.Properties;\nusing Wox.Plugin;\nusing Wox.Plugin.Common.Win32;\nusing Wox.Plugin.Logger;\n\nnamespace Microsoft.PowerToys.Run.Plugin.System.Components\n{\n    internal static class ResultHelper\n    {\n        private static bool executingEmptyRecycleBinTask;\n\n        internal static bool ExecuteCommand(bool confirm, string confirmationMessage, Action command)\n        {\n            if (confirm)\n            {\n                MessageBoxResult messageBoxResult = MessageBox.Show(\n                    confirmationMessage,\n                    Resources.Microsoft_plugin_sys_confirmation,\n                    MessageBoxButton.YesNo,\n                    MessageBoxImage.Warning);\n\n                if (messageBoxResult == MessageBoxResult.No)\n                {\n                    return false;\n                }\n            }\n\n            command();\n            return true;\n        }\n\n        internal static bool CopyToClipBoard(in string text)\n        {\n            try\n            {\n                Clipboard.Clear();\n                Clipboard.SetText(text);\n                return true;\n            }\n            catch (Exception exception)\n            {\n                Log.Exception(\"Can't copy to clipboard\", exception, typeof(ResultHelper));\n                return false;\n            }\n        }\n\n        internal static async void EmptyRecycleBinAsync(bool settingEmptyRBSuccesMsg)\n        {\n            if (executingEmptyRecycleBinTask)\n            {\n                _ = MessageBox.Show(Resources.Microsoft_plugin_sys_RecycleBin_EmptyTaskRunning, \"插件: \" + Resources.Microsoft_plugin_sys_plugin_name, MessageBoxButton.OK, MessageBoxImage.Information);\n                return;\n            }\n\n            await Task.Run(() => EmptyRecycleBinTask(settingEmptyRBSuccesMsg));\n        }\n\n        internal static List<ContextMenuResult> GetContextMenuForResult(Result result, bool settingEmptyRBSuccesMsg)\n        {\n            var contextMenu = new List<ContextMenuResult>();\n\n            if (!(result?.ContextData is SystemPluginContext contextData))\n            {\n                return contextMenu;\n            }\n\n            if (contextData.Type == ResultContextType.NetworkAdapterInfo)\n            {\n                contextMenu.Add(new ContextMenuResult()\n                {\n                    AcceleratorKey = Key.C,\n                    AcceleratorModifiers = ModifierKeys.Control,\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    Glyph = \"\\xE8C8\",                       // E8C8 => Symbol: Copy\n                    Title = Resources.Microsoft_plugin_sys_CopyDetails,\n                    Action = _ => CopyToClipBoard(contextData.Data),\n                });\n            }\n\n            if (contextData.Type == ResultContextType.RecycleBinCommand)\n            {\n                contextMenu.Add(new ContextMenuResult()\n                {\n                    AcceleratorKey = Key.Delete,\n                    AcceleratorModifiers = ModifierKeys.Shift, // Shift+Delete is the common key for deleting without recycle bin\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    Glyph = \"\\xE74D\",                       // E74D => Symbol: Delete\n                    Title = Resources.Microsoft_plugin_sys_RecycleBin_contextMenu,\n                    Action = _ =>\n                    {\n                        EmptyRecycleBinAsync(settingEmptyRBSuccesMsg);\n                        return true;\n                    },\n                });\n            }\n\n            return contextMenu;\n        }\n\n        /// <summary>\n        /// Method to process the empty recycle bin command in a separate task\n        /// </summary>\n        private static void EmptyRecycleBinTask(bool settingEmptyRBSuccesMsg)\n        {\n            executingEmptyRecycleBinTask = true;\n\n            // https://learn.microsoft.com/windows/win32/api/shellapi/nf-shellapi-shemptyrecyclebina/\n            // http://www.pinvoke.net/default.aspx/shell32/SHEmptyRecycleBin.html/\n            // If the recycle bin is already empty, it will return -2147418113 (0x8000FFFF (E_UNEXPECTED))\n            // If the user canceled the deletion task it will return 2147943623 (0x800704C7 (E_CANCELLED - The operation was canceled by the user.))\n            // On success it will return 0 (S_OK)\n            var result = NativeMethods.SHEmptyRecycleBin(IntPtr.Zero, 0);\n            if (result == (uint)HRESULT.E_UNEXPECTED)\n            {\n                _ = MessageBox.Show(Resources.Microsoft_plugin_sys_RecycleBin_IsEmpty, \"插件: \" + Resources.Microsoft_plugin_sys_plugin_name, MessageBoxButton.OK, MessageBoxImage.Information);\n            }\n            else if (result != (uint)HRESULT.S_OK && result != (uint)HRESULT.E_CANCELLED)\n            {\n                var errorDesc = Win32Helpers.MessageFromHResult((int)result);\n                var name = \"插件: \" + Resources.Microsoft_plugin_sys_plugin_name;\n                var message = $\"{Resources.Microsoft_plugin_sys_RecycleBin_ErrorMsg} {errorDesc}\";\n                Log.Error(message + \" - Please refer to https://msdn.microsoft.com/library/windows/desktop/aa378137 for more information.\", typeof(Commands));\n                _ = MessageBox.Show(message, name, MessageBoxButton.OK, MessageBoxImage.Error);\n            }\n\n            if (result == (uint)HRESULT.S_OK && settingEmptyRBSuccesMsg)\n            {\n                _ = MessageBox.Show(Resources.Microsoft_plugin_sys_RecycleBin_EmptySuccessMessage, \"插件: \" + Resources.Microsoft_plugin_sys_plugin_name, MessageBoxButton.OK, MessageBoxImage.Information);\n            }\n\n            executingEmptyRecycleBinTask = false;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Main.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Windows.Controls;\n\nusing ManagedCommon;\nusing Microsoft.PowerToys.Run.Plugin.System.Components;\nusing Microsoft.PowerToys.Run.Plugin.System.Properties;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Wox.Infrastructure;\nusing Wox.Plugin;\nusing Wox.Plugin.Common.Win32;\n\nnamespace Microsoft.PowerToys.Run.Plugin.System\n{\n    public class Main : IPlugin, IPluginI18n, ISettingProvider, IContextMenu, IDelayedExecutionPlugin\n    {\n        private PluginInitContext _context;\n\n        private bool _confirmSystemCommands;\n        private bool _showSuccessOnEmptyRB;\n\n        // [PowerToysCN]\n        // private bool _localizeSystemCommands;\n        private bool _reduceNetworkResultScore;\n        private bool _separateEmptyRB;\n\n        public string Name => Resources.Microsoft_plugin_sys_plugin_name;\n\n        public string Description => Resources.Microsoft_plugin_sys_plugin_description;\n\n        public static string PluginID => \"CEA08895D2544B019B2E9C5009600DF4\";\n\n        public string IconTheme { get; set; }\n\n        public bool IsBootedInUefiMode { get; set; }\n\n        public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()\n        {\n            new PluginAdditionalOption()\n            {\n                Key = \"ConfirmSystemCommands\",\n                DisplayLabel = Resources.confirm_system_commands,\n                Value = false,\n            },\n            new PluginAdditionalOption()\n            {\n                Key = \"ShowSuccessOnEmptyRB\",\n                DisplayLabel = Resources.Microsoft_plugin_sys_RecycleBin_ShowEmptySuccessMessage,\n                Value = false,\n            },\n\n            // [PowerToysCN]\n            // The original en-US resources are modified to Chinese.\n            // No need for an option to switch.\n            // new PluginAdditionalOption()\n            // {\n            //     Key = LocalizeSystemCommands,\n            //     DisplayLabel = Resources.Use_localized_system_commands,\n            //     Value = true,\n            // },\n            new PluginAdditionalOption()\n            {\n                Key = \"SeparateResultEmptyRB\",\n                DisplayLabel = Resources.Microsoft_plugin_sys_RecycleBin_ShowEmptySeparate,\n                Value = false,\n            },\n            new PluginAdditionalOption()\n            {\n                Key = \"ReduceNetworkResultScore\",\n                DisplayLabel = Resources.Reduce_Network_Result_Score,\n                DisplayDescription = Resources.Reduce_Network_Result_Score_Description,\n                Value = true,\n            },\n        };\n\n        public void Init(PluginInitContext context)\n        {\n            _context = context;\n            _context.API.ThemeChanged += OnThemeChanged;\n            UpdateIconTheme(_context.API.GetCurrentTheme());\n            IsBootedInUefiMode = Win32Helpers.GetSystemFirmwareType() == FirmwareType.Uefi;\n\n            // Log info if the system hasn't boot in uefi mode.\n            // (Because this is only going into the log we can ignore the fact that normally UEFI and BIOS are written upper case. No need to convert the enumeration value to upper case.)\n            if (!IsBootedInUefiMode)\n            {\n                Wox.Plugin.Logger.Log.Info($\"The UEFI command will not show to the user. The system has not booted in UEFI mode or the system does not have an UEFI firmware! (Detected type: {Win32Helpers.GetSystemFirmwareType()})\", typeof(Main));\n            }\n        }\n\n        public List<Result> Query(Query query)\n        {\n            List<Result> results = new List<Result>();\n\n            // [PowerToysCN]\n            // CultureInfo culture = _localizeSystemCommands ? CultureInfo.CurrentUICulture : new CultureInfo(\"en-US\");\n            CultureInfo culture = CultureInfo.CurrentUICulture;\n\n            if (query == null)\n            {\n                return results;\n            }\n\n            // normal system commands are fast and can be returned immediately\n            var systemCommands = Commands.GetSystemCommands(IsBootedInUefiMode, _separateEmptyRB, _confirmSystemCommands, _showSuccessOnEmptyRB, IconTheme, culture);\n            foreach (var c in systemCommands)\n            {\n                var resultMatch = StringMatcher.FuzzySearch(query.Search, c.Title);\n                if (resultMatch.Score > 0)\n                {\n                    c.Score = resultMatch.Score;\n                    c.TitleHighlightData = resultMatch.MatchData;\n                    results.Add(c);\n                }\n                else if (c?.ContextData is SystemPluginContext contextData)\n                {\n                    var searchTagMatch = StringMatcher.FuzzySearch(query.Search, contextData.SearchTag);\n                    if (searchTagMatch.Score > 0)\n                    {\n                        c.Score = resultMatch.Score;\n                        results.Add(c);\n                    }\n                }\n            }\n\n            // The following information result is not returned because delayed queries doesn't clear output if no results are available.\n            // On global queries the first word/part has to be 'ip', 'mac' or 'address' for network results\n            // string[] keywordList = Resources.ResourceManager.GetString(\"Microsoft_plugin_sys_Search_NetworkKeywordList\", culture).Split(\"; \");\n            // if (!string.IsNullOrEmpty(query.ActionKeyword) || keywordList.Any(x => query.Search.StartsWith(x, StringComparison.CurrentCultureIgnoreCase)))\n            // {\n            //    results.Add(new Result()\n            //    {\n            //        Title = \"Getting network information. Please wait ...\",\n            //        IcoPath = $\"Images\\\\networkAdapter.{IconTheme}.png\",\n            //        Score = StringMatcher.FuzzySearch(\"address\", \"ip address\").Score,\n            //    });\n            // }\n            return results;\n        }\n\n        public List<Result> Query(Query query, bool delayedExecution)\n        {\n            List<Result> results = new List<Result>();\n\n            // [PowerToysCN]\n            // CultureInfo culture = _localizeSystemCommands ? CultureInfo.CurrentUICulture : new CultureInfo(\"en-US\");\n            CultureInfo culture = CultureInfo.CurrentUICulture;\n\n            if (query == null)\n            {\n                return results;\n            }\n\n            // Network (ip and mac) results are slow with many network cards and returned delayed.\n            // On global queries the first word/part has to be 'ip', 'mac' or 'address' for network results\n            string[] keywordList = Resources.ResourceManager.GetString(\"Microsoft_plugin_sys_Search_NetworkKeywordList\", culture).Split(\"; \");\n            if (!string.IsNullOrEmpty(query.ActionKeyword) || keywordList.Any(x => query.Search.StartsWith(x, StringComparison.CurrentCultureIgnoreCase)))\n            {\n                var networkConnectionResults = Commands.GetNetworkConnectionResults(IconTheme, culture);\n                foreach (var r in networkConnectionResults)\n                {\n                    var resultMatch = StringMatcher.FuzzySearch(query.Search, r.SubTitle);\n                    if (resultMatch.Score > 0)\n                    {\n                        r.Score = _reduceNetworkResultScore ? (int)(resultMatch.Score * 65 / 100) : resultMatch.Score; // Adjust score to improve user experience and priority order\n                        r.SubTitleHighlightData = resultMatch.MatchData;\n                        results.Add(r);\n                    }\n                    else if (r?.ContextData is SystemPluginContext contextData)\n                    {\n                        var searchTagMatch = StringMatcher.FuzzySearch(query.Search, contextData.SearchTag);\n                        if (searchTagMatch.Score > 0)\n                        {\n                            r.Score = resultMatch.Score;\n                            results.Add(r);\n                        }\n                    }\n                }\n            }\n\n            return results;\n        }\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            return ResultHelper.GetContextMenuForResult(selectedResult, _showSuccessOnEmptyRB);\n        }\n\n        private void UpdateIconTheme(Theme theme)\n        {\n            if (theme == Theme.Light || theme == Theme.HighContrastWhite)\n            {\n                IconTheme = \"light\";\n            }\n            else\n            {\n                IconTheme = \"dark\";\n            }\n        }\n\n        private void OnThemeChanged(Theme currentTheme, Theme newTheme)\n        {\n            UpdateIconTheme(newTheme);\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Resources.Microsoft_plugin_sys_plugin_description;\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Resources.Microsoft_plugin_sys_plugin_name;\n        }\n\n        public Control CreateSettingPanel()\n        {\n            throw new NotImplementedException();\n        }\n\n        public void UpdateSettings(PowerLauncherPluginSettings settings)\n        {\n            var confirmSystemCommands = false;\n            var showSuccessOnEmptyRB = false;\n\n            // [PowerToysCN]\n            // var localizeSystemCommands = true;\n            var reduceNetworkResultScore = true;\n            var separateEmptyRB = false;\n\n            if (settings != null && settings.AdditionalOptions != null)\n            {\n                var optionConfirm = settings.AdditionalOptions.FirstOrDefault(x => x.Key == \"ConfirmSystemCommands\");\n                confirmSystemCommands = optionConfirm?.Value ?? confirmSystemCommands;\n\n                var optionEmptyRBSuccessMsg = settings.AdditionalOptions.FirstOrDefault(x => x.Key == \"ShowSuccessOnEmptyRB\");\n                showSuccessOnEmptyRB = optionEmptyRBSuccessMsg?.Value ?? showSuccessOnEmptyRB;\n\n                // [PowerToysCN]\n                // var optionLocalize = settings.AdditionalOptions.FirstOrDefault(x => x.Key == LocalizeSystemCommands);\n                // localizeSystemCommands = optionLocalize?.Value ?? true;\n                var optionNetworkScore = settings.AdditionalOptions.FirstOrDefault(x => x.Key == \"ReduceNetworkResultScore\");\n                reduceNetworkResultScore = optionNetworkScore?.Value ?? reduceNetworkResultScore;\n\n                var optionSeparateEmptyRB = settings.AdditionalOptions.FirstOrDefault(x => x.Key == \"SeparateResultEmptyRB\");\n                separateEmptyRB = optionSeparateEmptyRB?.Value ?? separateEmptyRB;\n            }\n\n            _confirmSystemCommands = confirmSystemCommands;\n            _showSuccessOnEmptyRB = showSuccessOnEmptyRB;\n\n            // [PowerToysCN]\n            // _localizeSystemCommands = localizeSystemCommands;\n            _reduceNetworkResultScore = reduceNetworkResultScore;\n            _separateEmptyRB = separateEmptyRB;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.System/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"confirm_system_commands\" xml:space=\"preserve\">\n    <value>执行系统命令时弹窗确认</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_AdapterDetails\" xml:space=\"preserve\">\n    <value>详细信息</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_AdapterName\" xml:space=\"preserve\">\n    <value>适配器名称</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Cable\" xml:space=\"preserve\">\n    <value>网线</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_confirmation\" xml:space=\"preserve\">\n    <value>请确认操作。</value>\n    <comment>Request confirmation</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Connected\" xml:space=\"preserve\">\n    <value>已连接</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_ConnectionDetails\" xml:space=\"preserve\">\n    <value>详细信息</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_ConnectionName\" xml:space=\"preserve\">\n    <value>连接名称</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_CopyDetails\" xml:space=\"preserve\">\n    <value>复制详细信息 (Ctrl+C)</value>\n    <comment>'Ctrl+C' is a shortcut</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Dhcp\" xml:space=\"preserve\">\n    <value>DHCP 服务器</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Disconnected\" xml:space=\"preserve\">\n    <value>已断开</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Dns\" xml:space=\"preserve\">\n    <value>DNS 服务器</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Gateways\" xml:space=\"preserve\">\n    <value>默认网关</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Gbps\" xml:space=\"preserve\">\n    <value>{0} Gbps</value>\n    <comment>Abbreviation of 'Gbits per seconds'. Don't translate the placeholder '{0}' as it is replaced in code.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_hibernate\" xml:space=\"preserve\">\n    <value>Hibernate 休眠</value>\n    <comment>This should align to the action in Windows of a hibernating your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_hibernate_confirmation\" xml:space=\"preserve\">\n    <value>确定休眠？</value>\n    <comment>This should align to the action in Windows of a hibernating your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_hibernate_description\" xml:space=\"preserve\">\n    <value>把运行状态保存在硬盘，然后关机，可以恢复所有状态</value>\n    <comment>This should align to the action in Windows of a hibernating your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Ip4Address\" xml:space=\"preserve\">\n    <value>IPv4 地址</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Ip4SubnetMask\" xml:space=\"preserve\">\n    <value>IPv4 子网掩码</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_ip4_description\" xml:space=\"preserve\">\n    <value>{0} 的 IPv4 地址</value>\n    <comment>Don't translate the placeholder '{0}' as it is replaced in code.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Ip6Address\" xml:space=\"preserve\">\n    <value>IPv6 地址</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Ip6Link\" xml:space=\"preserve\">\n    <value>IPv6 本地链路地址</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Ip6Site\" xml:space=\"preserve\">\n    <value>IPv6 本地站点地址</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Ip6Temp\" xml:space=\"preserve\">\n    <value>IPv6 临时地址</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Ip6Unique\" xml:space=\"preserve\">\n    <value>IPv6 唯一本地地址</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_ip6_description\" xml:space=\"preserve\">\n    <value>{0} 的 IPv6 地址</value>\n    <comment>Don't translate the placeholder '{0}' as it is replaced in code.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_lock\" xml:space=\"preserve\">\n    <value>Lock 锁定屏幕</value>\n    <comment>This should align to the action in Windows of a locking your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_lock_confirmation\" xml:space=\"preserve\">\n    <value>确定锁屏？</value>\n    <comment>This should align to the action in Windows of a locking your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_lock_description\" xml:space=\"preserve\">\n    <value>锁屏，登录以解锁</value>\n    <comment>This should align to the action in Windows of a locking your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Loopback\" xml:space=\"preserve\">\n    <value>回环</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_mac_description\" xml:space=\"preserve\">\n    <value>{0} ({1}) 的 MAC 地址</value>\n    <comment>Don't translate the placeholders '{0}' and '{1}' as they are replaced in code.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Mbps\" xml:space=\"preserve\">\n    <value>{0} Mbps</value>\n    <comment>Abbreviation of 'Mbits per seconds'. Don't translate the placeholder '{0}' as it is replaced in code.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_MobileBroadband\" xml:space=\"preserve\">\n    <value>移动数据</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_PhysicalAddress\" xml:space=\"preserve\">\n    <value>网卡地址 (MAC)</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_plugin_description\" xml:space=\"preserve\">\n    <value>执行系统命令（例如 “关机”、“锁屏”、“睡眠”）</value>\n    <comment>This should align to the actions in Windows relating to shutting down, signing out, locking, sleeping, restarting, emptying the recycle bin, and hibernating your computer. </comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_plugin_name\" xml:space=\"preserve\">\n    <value>系统命令</value>\n    <comment>Windows operating system commands.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin\" xml:space=\"preserve\">\n    <value>Recycle Bin 回收站</value>\n    <comment>Means the recycle bin folder in Explorer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBinEmptyResult\" xml:space=\"preserve\">\n    <value>Empty Recycle Bin 清空回收站</value>\n    <comment>This should align to the action in Windows of emptying the recycle bin on your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBinEmpty_description\" xml:space=\"preserve\">\n    <value>删除回收站所有文件</value>\n    <comment>This should align to the action in Windows of emptying the recycle bin on your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBinOpen\" xml:space=\"preserve\">\n    <value>Open Recycle Bin 打开回收站</value>\n    <comment>Means the recycle bin folder in Explorer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_contextMenu\" xml:space=\"preserve\">\n    <value>清空回收站 (Shift+Delete)</value>\n    <comment>This should align to the action in Windows of emptying the recycle bin on your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_description\" xml:space=\"preserve\">\n    <value>打开回收站</value>\n    <comment>This should align to the action in Windows of emptying the recycle bin on your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_EmptySuccessMessage\" xml:space=\"preserve\">\n    <value>回收站已清空。</value>\n    <comment>Means the recycle bin folder in Explorer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_EmptyTaskRunning\" xml:space=\"preserve\">\n    <value>正在清空回收站。</value>\n    <comment>Means the recycle bin folder in Explorer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_ErrorMsg\" xml:space=\"preserve\">\n    <value>回收站清空失败:</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_IsEmpty\" xml:space=\"preserve\">\n    <value>回收站已空。</value>\n    <comment>Means the recycle bin folder in Explorer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_searchTag\" xml:space=\"preserve\">\n    <value>Empty Recycle Bin 清空回收站</value>\n    <comment>This should align to the action in Windows of emptying the recycle bin on your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_ShowEmptySeparate\" xml:space=\"preserve\">\n    <value>分开显示回收站的打开和清空两个功能</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_RecycleBin_ShowEmptySuccessMessage\" xml:space=\"preserve\">\n    <value>清空回收站后提示成功</value>\n    <comment>Means the recycle bin folder in Explorer and \"emptying\" refers to \"Empty Recycle Bin\" command.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_restart_computer\" xml:space=\"preserve\">\n    <value>Restart 重启</value>\n    <comment>This should align to the action in Windows of a restarting your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_restart_computer_confirmation\" xml:space=\"preserve\">\n    <value>确定重启？</value>\n    <comment>This should align to the action in Windows of a restarting your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_restart_computer_description\" xml:space=\"preserve\">\n    <value>关闭所有应用，关闭系统，然后重新启动系统</value>\n    <comment>This should align to the action in Windows of a restarting your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Search_NetworkKeywordList\" xml:space=\"preserve\">\n    <value>ip; mac; 地址</value>\n    <comment>Translate 'ip' as 'ip' and not as 'ip address'. Same for 'mac'.)</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_shutdown_computer\" xml:space=\"preserve\">\n    <value>Shutdown 关机</value>\n    <comment>This should align to the action in Windows of a shutting down your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_shutdown_computer_confirmation\" xml:space=\"preserve\">\n    <value>确定关机？</value>\n    <comment>This should align to the action in Windows of a shutting down your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_shutdown_computer_description\" xml:space=\"preserve\">\n    <value>关闭所有应用，关闭系统，然后断开电源</value>\n    <comment>This should align to the action in Windows of a shutting down your computer.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_sign_out\" xml:space=\"preserve\">\n    <value>Sign out 注销</value>\n    <comment>This should align to the action in windows of a signing out back to the lock screen.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_sign_out_confirmation\" xml:space=\"preserve\">\n    <value>确定注销？</value>\n    <comment>This should align to the action in windows of a signing out back to the lock screen.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_sign_out_description\" xml:space=\"preserve\">\n    <value>关闭所有应用，注销账户，但不关闭系统</value>\n    <comment>This should align to the action in windows of a signing out back to the lock screen.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_sleep\" xml:space=\"preserve\">\n    <value>Sleep 睡眠</value>\n    <comment>This should align to the action in Windows of a making your computer go to sleep.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_sleep_confirmation\" xml:space=\"preserve\">\n    <value>确定睡眠？</value>\n    <comment>This should align to the action in Windows of a making your computer go to sleep.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_sleep_description\" xml:space=\"preserve\">\n    <value>将运行中的应用冻结，关闭不必要的硬件并待机</value>\n    <comment>This should align to the action in Windows of a making your computer go to sleep.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Speed\" xml:space=\"preserve\">\n    <value>速度</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_State\" xml:space=\"preserve\">\n    <value>状态</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_SubTitle_CopyHint\" xml:space=\"preserve\">\n    <value>点击复制</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Suffix\" xml:space=\"preserve\">\n    <value>DNS 后缀</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_TunnelConnection\" xml:space=\"preserve\">\n    <value>隧道</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Type\" xml:space=\"preserve\">\n    <value>类型</value>\n    <comment>Means type like category. Here it means network interface type (ethernet, wifi, ...).</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_uefi\" xml:space=\"preserve\">\n    <value>UEFI 固件设置</value>\n    <comment>This should align to the action in Windows Recovery Environment that restart into uefi settings.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_uefi_confirmation\" xml:space=\"preserve\">\n    <value>你将在电脑重启后进入主板 UEFI 固件设置，是否确定？</value>\n    <comment>This should align to the action in Windows Recovery Environment that restart into uefi settings.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_uefi_description\" xml:space=\"preserve\">\n    <value>重启电脑，然后进入主板 UEFI 固件设置（需要管理员权限）</value>\n    <comment>This should align to the action in Windows Recovery Environment that restart into uefi settings.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Unknown\" xml:space=\"preserve\">\n    <value>未知</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_Wins\" xml:space=\"preserve\">\n    <value>WINS 服务器</value>\n  </data>\n  <data name=\"Microsoft_plugin_sys_WirelessLan\" xml:space=\"preserve\">\n    <value>Wifi</value>\n  </data>\n  <data name=\"Reduce_Network_Result_Score\" xml:space=\"preserve\">\n    <value>降低 “IP” “MAC” 的搜索优先级</value>\n  </data>\n  <data name=\"Reduce_Network_Result_Score_Description\" xml:space=\"preserve\">\n    <value>优化搜索结果显示顺序（放在更后面），但是更难搜到</value>\n  </data>\n  <data name=\"Use_localized_system_commands\" xml:space=\"preserve\">\n    <value>喵呜 (owo)/</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.TimeDate/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Microsoft_plugin_timedate_CopyToClipboard\" xml:space=\"preserve\">\n    <value>复制 (Ctrl+C)</value>\n    <comment>'Ctrl+C' is a shortcut</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_copy_failed\" xml:space=\"preserve\">\n    <value>复制失败</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Date\" xml:space=\"preserve\">\n    <value>日期</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_DateAndTime\" xml:space=\"preserve\">\n    <value>日期和时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_DateAndTimeUtc\" xml:space=\"preserve\">\n    <value>日期和时间（UTC）</value>\n    <comment>'UTC' means here 'Universal Time Convention'</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Day\" xml:space=\"preserve\">\n    <value>星期</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_DayMonth\" xml:space=\"preserve\">\n    <value>月日</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_DayOfMonth\" xml:space=\"preserve\">\n    <value>本月第几天</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_DayOfWeek\" xml:space=\"preserve\">\n    <value>本周第几天</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_DayOfYear\" xml:space=\"preserve\">\n    <value>本年第几天</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Era\" xml:space=\"preserve\">\n    <value>纪元</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_EraAbbreviation\" xml:space=\"preserve\">\n    <value>纪元缩写</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_ErrorResultSubTitle\" xml:space=\"preserve\">\n    <value>可用前缀：“u” 表示 Unix 时间戳，“ums” 表示 Unix 毫秒时间戳, “ft” 表示 Windows 文件时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_ErrorResultTitle\" xml:space=\"preserve\">\n    <value>错误: 数字输入无效</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Hour\" xml:space=\"preserve\">\n    <value>小时</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Iso8601\" xml:space=\"preserve\">\n    <value>ISO 8601</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Iso8601Utc\" xml:space=\"preserve\">\n    <value>ISO 8601（UTC）</value>\n    <comment>'UTC' means here 'Universal Time Convention'</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Iso8601Zone\" xml:space=\"preserve\">\n    <value>ISO 8601 +时区</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Iso8601ZoneUtc\" xml:space=\"preserve\">\n    <value>ISO 8601（UTC）+时区</value>\n    <comment>'UTC' means here 'Universal Time Convention'</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_filename_compatible\" xml:space=\"preserve\">\n    <value>文件名时间</value>\n    <comment>The format allows for embedding in filenames</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Millisecond\" xml:space=\"preserve\">\n    <value>毫秒</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Minute\" xml:space=\"preserve\">\n    <value>分钟</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Month\" xml:space=\"preserve\">\n    <value>月份</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_MonthOfYear\" xml:space=\"preserve\">\n    <value>本年第几月</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_MonthYear\" xml:space=\"preserve\">\n    <value>年月</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Now\" xml:space=\"preserve\">\n    <value>当前时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_NowUtc\" xml:space=\"preserve\">\n    <value>当前时间（UTC）</value>\n    <comment>'UTC' means here 'Universal Time Convention'</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_plugin_description\" xml:space=\"preserve\">\n    <value>获取时间与日期，支持自定义时间戳（比如：“{0}” “{1}” “{2}” “{3}”）</value>\n    <comment>Do not translate the placeholders like '{0}' because it will be replaced in code.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_plugin_description_example_calendarWeek\" xml:space=\"preserve\">\n    <value>星期</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_plugin_description_example_day\" xml:space=\"preserve\">\n    <value>日期</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_plugin_description_example_time\" xml:space=\"preserve\">\n    <value>时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_plugin_name\" xml:space=\"preserve\">\n    <value>时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Rfc1123\" xml:space=\"preserve\">\n    <value>RFC1123</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagDate\" xml:space=\"preserve\">\n    <value>日期</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagDateNow\" xml:space=\"preserve\">\n    <value>当前日期; 现在</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagEra\" xml:space=\"preserve\">\n    <value>年份; 时代; 日期</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagEraNow\" xml:space=\"preserve\">\n    <value>当前年份; 当前时代; 当前日期; 现在</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagFormat\" xml:space=\"preserve\">\n    <value>日期和时间; 时间和日期</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagFormatNow\" xml:space=\"preserve\">\n    <value>当前日期和时间; 当前时间和日期; 现在</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagTime\" xml:space=\"preserve\">\n    <value>时间</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SearchTagTimeNow\" xml:space=\"preserve\">\n    <value>当前时间; 现在</value>\n    <comment>Don't change order</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Search_ConjunctionList\" xml:space=\"preserve\">\n    <value>for; and; nor; but; or; so; 与; 和; 或; 是; 的; 几; 什么</value>\n    <comment>List of conjunctions. We don't add 'yet' because this can be a synonym of 'now' which might be problematic on localized searches.</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Second\" xml:space=\"preserve\">\n    <value>秒</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingDateWithWeekday\" xml:space=\"preserve\">\n    <value>日期显示日月名称</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingDateWithWeekday_Description\" xml:space=\"preserve\">\n    <value>针对 “日期” 和 “现在”</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingHideNumberMessageOnGlobalQuery\" xml:space=\"preserve\">\n    <value>全局搜索时隐藏 “数字输入无效” 结果</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingOnlyDateTimeNowGlobal\" xml:space=\"preserve\">\n    <value>全局搜索只显示当前 “时间” “日期” “现在”</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingOnlyDateTimeNowGlobal_Description\" xml:space=\"preserve\">\n    <value>无论如何，搜索的第一个字必须对上才能搜到</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingTimeWithSeconds\" xml:space=\"preserve\">\n    <value>时间显示秒数</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingTimeWithSeconds_Description\" xml:space=\"preserve\">\n    <value>针对 “时间” 和 “现在”</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SubTitleNote\" xml:space=\"preserve\">\n    <value>点击或按 Ctrl+C 复制</value>\n    <comment>'Ctrl+C' is a shortcut</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Time\" xml:space=\"preserve\">\n    <value>时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_TimeUtc\" xml:space=\"preserve\">\n    <value>时间（UTC）</value>\n    <comment>'UTC' means here 'Universal Time Convention'</comment>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_ToolTipAlternativeSearchTag\" xml:space=\"preserve\">\n    <value>备用关键字：</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_UniversalTime\" xml:space=\"preserve\">\n    <value>通用时间格式：YYYY-MM-DD hh:mm:ss</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Unix\" xml:space=\"preserve\">\n    <value>Unix 纪元时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_WeekOfMonth\" xml:space=\"preserve\">\n    <value>本月第几周</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_WeekOfYear\" xml:space=\"preserve\">\n    <value>本年第几周</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_WindowsFileTime\" xml:space=\"preserve\">\n    <value>Windows 文件时间（64 位整数）</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Year\" xml:space=\"preserve\">\n    <value>年份</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Unix_Milliseconds\" xml:space=\"preserve\">\n    <value>Unix 纪元毫秒时间</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek\" xml:space=\"preserve\">\n    <value>每周第一天</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek_Friday\" xml:space=\"preserve\">\n    <value>星期五</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek_Monday\" xml:space=\"preserve\">\n    <value>星期一</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek_Saturday\" xml:space=\"preserve\">\n    <value>星期六</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek_Sunday\" xml:space=\"preserve\">\n    <value>星期日</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek_Thursday\" xml:space=\"preserve\">\n    <value>星期四</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek_Tuesday\" xml:space=\"preserve\">\n    <value>星期二</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstDayOfWeek_Wednesday\" xml:space=\"preserve\">\n    <value>星期三</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstWeekRule\" xml:space=\"preserve\">\n    <value>每年第一周</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstWeekRule_Description\" xml:space=\"preserve\">\n    <value>设置每年第一周的计算规则</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstWeekRule_FirstDay\" xml:space=\"preserve\">\n    <value>每年第一天所在的一周</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstWeekRule_FirstFourDayWeek\" xml:space=\"preserve\">\n    <value>每年第一个满四天的一周</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_SettingFirstWeekRule_FirstFullWeek\" xml:space=\"preserve\">\n    <value>每年第一个完整的一周</value>\n  </data>\n  <data name=\"Microsoft_plugin_timedate_Setting_UseSystemSetting\" xml:space=\"preserve\">\n    <value>使用系统设置</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsSettings/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"About\" xml:space=\"preserve\">\n    <value>关于</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"access.cpl\" xml:space=\"preserve\">\n    <value>access.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"AccessibilityOptions\" xml:space=\"preserve\">\n    <value>轻松使用设置中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"AccessoryApps\" xml:space=\"preserve\">\n    <value>辅助程序</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"AccessWorkOrSchool\" xml:space=\"preserve\">\n    <value>连接工作或学校帐户</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"AccountInfo\" xml:space=\"preserve\">\n    <value>帐户信息</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"Accounts\" xml:space=\"preserve\">\n    <value>账户</value>\n    <comment>Area SurfaceHub</comment>\n  </data>\n  <data name=\"ActionCenter\" xml:space=\"preserve\">\n    <value>操作中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Activation\" xml:space=\"preserve\">\n    <value>激活</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"ActivityHistory\" xml:space=\"preserve\">\n    <value>活动历史记录</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"AddDevices\" xml:space=\"preserve\">\n    <value>添加硬件</value>\n  </data>\n  <data name=\"AddHardware\" xml:space=\"preserve\">\n    <value>添加设备</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"AddRemovePrograms\" xml:space=\"preserve\">\n    <value>添加或删除程序</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"AddYourPhone\" xml:space=\"preserve\">\n    <value>添加手机</value>\n    <comment>Area Phone</comment>\n  </data>\n  <data name=\"AdministrativeTools\" xml:space=\"preserve\">\n    <value>Windows 工具</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"AdvancedDisplaySettings\" xml:space=\"preserve\">\n    <value>高级显示设置</value>\n    <comment>Area System, only available on devices that support advanced display options</comment>\n  </data>\n  <data name=\"AdvancedGraphics\" xml:space=\"preserve\">\n    <value>高级图形</value>\n  </data>\n  <data name=\"AdvertisingId\" xml:space=\"preserve\">\n    <value>广告 ID</value>\n    <comment>Area Privacy, Deprecated in Windows 10, version 1809 and later</comment>\n  </data>\n  <data name=\"AirplaneMode\" xml:space=\"preserve\">\n    <value>飞行模式</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"AltAndTab\" xml:space=\"preserve\">\n    <value>Alt+Tab</value>\n    <comment>Means the key  combination \"Tabulator+Alt\" on the keyboard</comment>\n  </data>\n  <data name=\"AlternativeName\" xml:space=\"preserve\">\n    <value>代称</value>\n  </data>\n  <data name=\"Animations\" xml:space=\"preserve\">\n    <value>动画效果</value>\n  </data>\n  <data name=\"AppColor\" xml:space=\"preserve\">\n    <value>应用颜色</value>\n  </data>\n  <data name=\"AppControlPanel\" xml:space=\"preserve\">\n    <value>控制面板</value>\n    <comment>Type of the setting is a \"(legacy) Control Panel setting\"</comment>\n  </data>\n  <data name=\"AppDiagnostics\" xml:space=\"preserve\">\n    <value>应用诊断</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"AppFeatures\" xml:space=\"preserve\">\n    <value>应用功能</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"Application\" xml:space=\"preserve\">\n    <value>应用</value>\n    <comment>Short/modern name for application</comment>\n  </data>\n  <data name=\"AppMMC\" xml:space=\"preserve\">\n    <value>Microsoft 管理控制台</value>\n  </data>\n  <data name=\"AppsAndFeatures\" xml:space=\"preserve\">\n    <value>应用和功能</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"AppSettingsApp\" xml:space=\"preserve\">\n    <value>设置</value>\n    <comment>Type of the setting is a \"Modern Windows settings\". We use the same term as used in start menu search at the moment. </comment>\n  </data>\n  <data name=\"AppsForWebsites\" xml:space=\"preserve\">\n    <value>可使用网站打开的应用</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"AppVolumeAndDevicePreferences\" xml:space=\"preserve\">\n    <value>应用音量和设备首选项</value>\n    <comment>Area System, Added in Windows 10, version 1903</comment>\n  </data>\n  <data name=\"appwiz.cpl\" xml:space=\"preserve\">\n    <value>appwiz.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Area\" xml:space=\"preserve\">\n    <value>类别</value>\n    <comment>Mean the settings area or settings category</comment>\n  </data>\n  <data name=\"AreaAccounts\" xml:space=\"preserve\">\n    <value>账户</value>\n  </data>\n  <data name=\"AreaAdministrativeTools\" xml:space=\"preserve\">\n    <value>Windows 工具</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"AreaAppearanceAndPersonalization\" xml:space=\"preserve\">\n    <value>外观和个性化</value>\n  </data>\n  <data name=\"AreaApps\" xml:space=\"preserve\">\n    <value>应用</value>\n  </data>\n  <data name=\"AreaBluetoothAndDevices11\" xml:space=\"preserve\">\n    <value>蓝牙和其他设备</value>\n    <comment>Area Bluetooth&amp;Devices in Win11 Settings app</comment>\n  </data>\n  <data name=\"AreaClockAndRegion\" xml:space=\"preserve\">\n    <value>时钟和区域</value>\n  </data>\n  <data name=\"AreaCortana\" xml:space=\"preserve\">\n    <value>Cortana</value>\n  </data>\n  <data name=\"AreaDevices\" xml:space=\"preserve\">\n    <value>设备</value>\n  </data>\n  <data name=\"AreaEaseOfAccess\" xml:space=\"preserve\">\n    <value>轻松使用</value>\n  </data>\n  <data name=\"AreaExtras\" xml:space=\"preserve\">\n    <value>附加设置</value>\n  </data>\n  <data name=\"AreaGaming\" xml:space=\"preserve\">\n    <value>游戏</value>\n  </data>\n  <data name=\"AreaHardwareAndSound\" xml:space=\"preserve\">\n    <value>硬件和声音</value>\n  </data>\n  <data name=\"AreaMixedReality\" xml:space=\"preserve\">\n    <value>混合现实</value>\n  </data>\n  <data name=\"AreaNetworkAndInternet\" xml:space=\"preserve\">\n    <value>网络和 Internet</value>\n  </data>\n  <data name=\"AreaPersonalization\" xml:space=\"preserve\">\n    <value>个性化</value>\n  </data>\n  <data name=\"AreaPhone\" xml:space=\"preserve\">\n    <value>手机</value>\n  </data>\n  <data name=\"AreaPrivacy\" xml:space=\"preserve\">\n    <value>隐私</value>\n  </data>\n  <data name=\"AreaPrograms\" xml:space=\"preserve\">\n    <value>程序</value>\n  </data>\n  <data name=\"AreaSecurityAndMaintenance\" xml:space=\"preserve\">\n    <value>安全和维护</value>\n    <comment>Area Security and Maintenance in legacy Control Panel app.</comment>\n  </data>\n  <data name=\"AreaSurfaceHub\" xml:space=\"preserve\">\n    <value>SurfaceHub</value>\n  </data>\n  <data name=\"AreaSystem\" xml:space=\"preserve\">\n    <value>系统</value>\n  </data>\n  <data name=\"AreaSystemAndSecurity\" xml:space=\"preserve\">\n    <value>系统和安全</value>\n  </data>\n  <data name=\"AreaSystemPropertiesAdvanced\" xml:space=\"preserve\">\n    <value>系统属性</value>\n    <comment>System Properties dialog sysdm.cpl</comment>\n  </data>\n  <data name=\"AreaTimeAndLanguage\" xml:space=\"preserve\">\n    <value>时间和语言</value>\n  </data>\n  <data name=\"AreaUpdateAndSecurity\" xml:space=\"preserve\">\n    <value>更新和安全</value>\n  </data>\n  <data name=\"AreaUserAccounts\" xml:space=\"preserve\">\n    <value>用户帐户</value>\n  </data>\n  <data name=\"AssignedAccess\" xml:space=\"preserve\">\n    <value>受指派的存取权</value>\n  </data>\n  <data name=\"Audio\" xml:space=\"preserve\">\n    <value>音频</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"AudioAlerts\" xml:space=\"preserve\">\n    <value>音频通知</value>\n  </data>\n  <data name=\"AudioAndSpeech\" xml:space=\"preserve\">\n    <value>音频和语音</value>\n    <comment>Area MixedReality, only available if the Mixed Reality Portal app is installed.</comment>\n  </data>\n  <data name=\"AuthorizationManager\" xml:space=\"preserve\">\n    <value>授权管理器</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"AutomaticFileDownloads\" xml:space=\"preserve\">\n    <value>自动文件下载</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"AutoPlay\" xml:space=\"preserve\">\n    <value>自动播放</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"Background\" xml:space=\"preserve\">\n    <value>背景</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"BackgroundApps\" xml:space=\"preserve\">\n    <value>后台应用</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"Backup\" xml:space=\"preserve\">\n    <value>备份</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"BackupAndRestore\" xml:space=\"preserve\">\n    <value>备份和还原</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"BatterySaver\" xml:space=\"preserve\">\n    <value>节电模式</value>\n    <comment>Area System, only available on devices that have a battery, such as a tablet</comment>\n  </data>\n  <data name=\"BatterySaverSettings\" xml:space=\"preserve\">\n    <value>节电模式设置</value>\n    <comment>Area System, only available on devices that have a battery, such as a tablet</comment>\n  </data>\n  <data name=\"BatterySaverUsageDetails\" xml:space=\"preserve\">\n    <value>节电模式使用情况</value>\n  </data>\n  <data name=\"BatteryUse\" xml:space=\"preserve\">\n    <value>电池使用情况</value>\n    <comment>Area System, only available on devices that have a battery, such as a tablet</comment>\n  </data>\n  <data name=\"BiometricDevices\" xml:space=\"preserve\">\n    <value>生物识别设备</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"BitLockerDriveEncryption\" xml:space=\"preserve\">\n    <value>BitLocker 驱动器加密</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"BlueLight\" xml:space=\"preserve\">\n    <value>蓝光</value>\n  </data>\n  <data name=\"Bluetooth\" xml:space=\"preserve\">\n    <value>蓝牙</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"BluetoothAndDevices10\" xml:space=\"preserve\">\n    <value>蓝牙和其他设备</value>\n    <comment>Page Bluetooth and devices in Win10 Settings app</comment>\n  </data>\n  <data name=\"BluetoothDevices\" xml:space=\"preserve\">\n    <value>蓝牙设备</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"BlueYellow\" xml:space=\"preserve\">\n    <value>蓝黄色</value>\n  </data>\n  <data name=\"BopomofoIme\" xml:space=\"preserve\">\n    <value>注音输入法（Bopomofo IME）</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"bpmf\" xml:space=\"preserve\">\n    <value>bpmf</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"Broadcasting\" xml:space=\"preserve\">\n    <value>广播</value>\n    <comment>Area Gaming</comment>\n  </data>\n  <data name=\"bthprops.cpl\" xml:space=\"preserve\">\n    <value>bthprops.cpl</value>\n  </data>\n  <data name=\"Calendar\" xml:space=\"preserve\">\n    <value>日历</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"CallHistory\" xml:space=\"preserve\">\n    <value>通话记录</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"calling\" xml:space=\"preserve\">\n    <value>通话</value>\n  </data>\n  <data name=\"Camera\" xml:space=\"preserve\">\n    <value>相机</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"CangjieIme\" xml:space=\"preserve\">\n    <value>仓颉输入法（Cangjie IME）</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"CapsLock\" xml:space=\"preserve\">\n    <value>大写锁定键 CapsLock</value>\n    <comment>Mean the \"Caps Lock\" key</comment>\n  </data>\n  <data name=\"CellularAndSim\" xml:space=\"preserve\">\n    <value>手机网络和 SIM</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"CertificatesCurrentUser\" xml:space=\"preserve\">\n    <value>证书 - 当前用户</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"CertificatesLocalComputer\" xml:space=\"preserve\">\n    <value>证书 - 本地计算机</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"ChangePrograms\" xml:space=\"preserve\">\n    <value>更改程序</value>\n  </data>\n  <data name=\"ChangeScreenSaver\" xml:space=\"preserve\">\n    <value>更改屏幕保护程序</value>\n  </data>\n  <data name=\"ChangeUACSettings\" xml:space=\"preserve\">\n    <value>更改用户帐户控制设置</value>\n  </data>\n  <data name=\"ChooseWhichFoldersAppearOnStart\" xml:space=\"preserve\">\n    <value>选择“开始”菜单上显示的文件夹</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"ClientServiceForNetWare\" xml:space=\"preserve\">\n    <value>NetWare 客户端服务</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Clipboard\" xml:space=\"preserve\">\n    <value>剪贴板</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"ClosedCaptions\" xml:space=\"preserve\">\n    <value>字幕</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"collab.cpl\" xml:space=\"preserve\">\n    <value>collab.cpl</value>\n  </data>\n  <data name=\"ColorFilters\" xml:space=\"preserve\">\n    <value>颜色滤镜</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"ColorManagement\" xml:space=\"preserve\">\n    <value>颜色管理</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Colors\" xml:space=\"preserve\">\n    <value>颜色</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"Command\" xml:space=\"preserve\">\n    <value>命令</value>\n    <comment>The command to direct start a setting</comment>\n  </data>\n  <data name=\"ComObjects\" xml:space=\"preserve\">\n    <value>COM 对象</value>\n  </data>\n  <data name=\"ComponentServices\" xml:space=\"preserve\">\n    <value>组件服务</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"ComputerManagement\" xml:space=\"preserve\">\n    <value>计算机管理</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"ConnectableDevices\" xml:space=\"preserve\">\n    <value>可连接的设备</value>\n  </data>\n  <data name=\"ConnectedDevices\" xml:space=\"preserve\">\n    <value>已连接的设备</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"ConnectPanel\" xml:space=\"preserve\">\n    <value>连接面板</value>\n  </data>\n  <data name=\"ConnectWirelessAudio\" xml:space=\"preserve\">\n    <value>连接到无线音频设备</value>\n  </data>\n  <data name=\"ConnectWirelessDisplay\" xml:space=\"preserve\">\n    <value>连接到无线显示器</value>\n  </data>\n  <data name=\"Contacts\" xml:space=\"preserve\">\n    <value>联系人</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"CopyCommand\" xml:space=\"preserve\">\n    <value>复制命令</value>\n  </data>\n  <data name=\"CoreIsolation\" xml:space=\"preserve\">\n    <value>核心隔离</value>\n    <comment>Means the protection of the system core</comment>\n  </data>\n  <data name=\"Cortana\" xml:space=\"preserve\">\n    <value>Cortana</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"CortanaAcrossMyDevices\" xml:space=\"preserve\">\n    <value>跨设备使用 Cortana</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"CortanaLanguage\" xml:space=\"preserve\">\n    <value>Cortana - 语言</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"CreateAndFormatHardDiskPartitions\" xml:space=\"preserve\">\n    <value>创建与格式化磁盘分区</value>\n  </data>\n  <data name=\"CredentialManager\" xml:space=\"preserve\">\n    <value>凭据管理器</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Crossdevice\" xml:space=\"preserve\">\n    <value>跨设备</value>\n  </data>\n  <data name=\"CustomDevices\" xml:space=\"preserve\">\n    <value>自定义设备</value>\n  </data>\n  <data name=\"DarkColor\" xml:space=\"preserve\">\n    <value>深色</value>\n  </data>\n  <data name=\"DarkMode\" xml:space=\"preserve\">\n    <value>深色模式</value>\n  </data>\n  <data name=\"DataUsage\" xml:space=\"preserve\">\n    <value>数据使用量</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"DateAndTime\" xml:space=\"preserve\">\n    <value>日期和时间</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"DefaultApps\" xml:space=\"preserve\">\n    <value>默认应用</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"DefaultCamera\" xml:space=\"preserve\">\n    <value>默认相机</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"DefaultLocation\" xml:space=\"preserve\">\n    <value>默认位置</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"DefaultPrograms\" xml:space=\"preserve\">\n    <value>默认程序</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"DefaultSaveLocations\" xml:space=\"preserve\">\n    <value>默认保存位置</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"DefenderFirewallAdvancedSecurity\" xml:space=\"preserve\">\n    <value>高级安全 Windows Defender 防火墙</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"DeliveryOptimization\" xml:space=\"preserve\">\n    <value>传递优化</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"desk.cpl\" xml:space=\"preserve\">\n    <value>desk.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"DesktopThemes\" xml:space=\"preserve\">\n    <value>桌面主题</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"deuteranopia\" xml:space=\"preserve\">\n    <value>绿色盲</value>\n    <comment>Medical: Mean you don't can see red colors</comment>\n  </data>\n  <data name=\"DeviceDiscovery\" xml:space=\"preserve\">\n    <value>发现设备</value>\n  </data>\n  <data name=\"DeviceManager\" xml:space=\"preserve\">\n    <value>设备管理器</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"DeviceManagerSnapIn\" xml:space=\"preserve\">\n    <value>设备管理器</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"Devices\" xml:space=\"preserve\">\n    <value>设备</value>\n  </data>\n  <data name=\"DevicesAndPrinters\" xml:space=\"preserve\">\n    <value>设备和打印机</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Dhcp\" xml:space=\"preserve\">\n    <value>DHCP</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"DialUp\" xml:space=\"preserve\">\n    <value>拨号</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"DirectAccess\" xml:space=\"preserve\">\n    <value>DirectAccess</value>\n    <comment>Area NetworkAndInternet, only available if DirectAccess is enabled</comment>\n  </data>\n  <data name=\"DirectOpenYourPhone\" xml:space=\"preserve\">\n    <value>直接打开你的手机</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"DiskManagement\" xml:space=\"preserve\">\n    <value>磁盘管理</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"Display\" xml:space=\"preserve\">\n    <value>显示</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"DisplayProperties\" xml:space=\"preserve\">\n    <value>显示属性</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"DNS\" xml:space=\"preserve\">\n    <value>DNS</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"Documents\" xml:space=\"preserve\">\n    <value>文档</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"DuplicatingMyDisplay\" xml:space=\"preserve\">\n    <value>当我在使用投影时</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"DuringTheseHours\" xml:space=\"preserve\">\n    <value>在这些时间段内</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"EaseOfAccessCenter\" xml:space=\"preserve\">\n    <value>轻松使用设置中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"EditEnvironmentVariables\" xml:space=\"preserve\">\n    <value>编辑环境变量</value>\n    <comment>Used as AltName on EditSystemEnvironmentVars settings to make both entries available via 'Edit environment variables'.</comment>\n  </data>\n  <data name=\"Edition\" xml:space=\"preserve\">\n    <value>发行版</value>\n    <comment>Means the \"Windows Edition\"</comment>\n  </data>\n  <data name=\"EditSystemEnvironmentVariables\" xml:space=\"preserve\">\n    <value>编辑系统环境变量</value>\n  </data>\n  <data name=\"EditUserEnvironmentVariables\" xml:space=\"preserve\">\n    <value>编辑帐户的环境变量</value>\n  </data>\n  <data name=\"Email\" xml:space=\"preserve\">\n    <value>电子邮件</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"EmailAndAppAccounts\" xml:space=\"preserve\">\n    <value>电子邮件和帐户</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"Encryption\" xml:space=\"preserve\">\n    <value>设备加密</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"Environment\" xml:space=\"preserve\">\n    <value>环境</value>\n    <comment>Area MixedReality, only available if the Mixed Reality Portal app is installed.</comment>\n  </data>\n  <data name=\"EnvVars\" xml:space=\"preserve\">\n    <value>环境变量 (Env vars)</value>\n    <comment>Short english form. Don't translate!</comment>\n  </data>\n  <data name=\"Ethernet\" xml:space=\"preserve\">\n    <value>以太网</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"EventViewer\" xml:space=\"preserve\">\n    <value>事件查看器</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"ExploitProtection\" xml:space=\"preserve\">\n    <value>漏洞保护</value>\n  </data>\n  <data name=\"Extras\" xml:space=\"preserve\">\n    <value>附加设置</value>\n    <comment>Area Extra, , only used for setting of 3rd-Party tools</comment>\n  </data>\n  <data name=\"EyeControl\" xml:space=\"preserve\">\n    <value>目视控制</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"EyeTracker\" xml:space=\"preserve\">\n    <value>目视跟踪器</value>\n    <comment>Area Privacy, requires eyetracker hardware</comment>\n  </data>\n  <data name=\"FamilyAndOtherPeople\" xml:space=\"preserve\">\n    <value>家庭和其他用户</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"FeedbackAndDiagnostics\" xml:space=\"preserve\">\n    <value>诊断和反馈</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"FileSystem\" xml:space=\"preserve\">\n    <value>文件系统</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"FindFast\" xml:space=\"preserve\">\n    <value>快速搜索</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"findfast.cpl\" xml:space=\"preserve\">\n    <value>findfast.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"FindMyDevice\" xml:space=\"preserve\">\n    <value>查找我的设备</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"Firewall\" xml:space=\"preserve\">\n    <value>防火墙</value>\n  </data>\n  <data name=\"Firewall.cpl\" xml:space=\"preserve\">\n    <value>Firewall.cpl</value>\n  </data>\n  <data name=\"FocusAssistQuietHours\" xml:space=\"preserve\">\n    <value>专注助手 - 安静时间段</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"FocusAssistQuietMoments\" xml:space=\"preserve\">\n    <value>专注助手 - 安静时刻</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"FolderOptions\" xml:space=\"preserve\">\n    <value>文件资源管理器选项</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Fonts\" xml:space=\"preserve\">\n    <value>字体</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"ForDevelopers\" xml:space=\"preserve\">\n    <value>开发者选项</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"GameBar\" xml:space=\"preserve\">\n    <value>游戏栏</value>\n    <comment>Area Gaming</comment>\n  </data>\n  <data name=\"GameControllers\" xml:space=\"preserve\">\n    <value>游戏控制器</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"GameDvr\" xml:space=\"preserve\">\n    <value>屏幕截图</value>\n    <comment>Area Gaming</comment>\n  </data>\n  <data name=\"GameMode\" xml:space=\"preserve\">\n    <value>游戏模式</value>\n    <comment>Area Gaming</comment>\n  </data>\n  <data name=\"Gateway\" xml:space=\"preserve\">\n    <value>网关</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"General\" xml:space=\"preserve\">\n    <value>常规</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"GetPrograms\" xml:space=\"preserve\">\n    <value>获得程序</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"GettingStarted\" xml:space=\"preserve\">\n    <value>入门</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Glance\" xml:space=\"preserve\">\n    <value>概览</value>\n    <comment>Area Personalization, Deprecated in Windows 10, version 1809 and later</comment>\n  </data>\n  <data name=\"GPT\" xml:space=\"preserve\">\n    <value>GPT</value>\n  </data>\n  <data name=\"GraphicsSettings\" xml:space=\"preserve\">\n    <value>图形设置</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"Grayscale\" xml:space=\"preserve\">\n    <value>灰度</value>\n  </data>\n  <data name=\"GreenWeek\" xml:space=\"preserve\">\n    <value>绿色弱</value>\n    <comment>Mean you don't can see green colors</comment>\n  </data>\n  <data name=\"GroupPolicy\" xml:space=\"preserve\">\n    <value>Group Policy</value>\n  </data>\n  <data name=\"hdwwiz.cpl\" xml:space=\"preserve\">\n    <value>hdwwiz.cpl</value>\n  </data>\n  <data name=\"HeadsetDisplay\" xml:space=\"preserve\">\n    <value>头戴显示设备显示</value>\n    <comment>Area MixedReality, only available if the Mixed Reality Portal app is installed.</comment>\n  </data>\n  <data name=\"HighContrast\" xml:space=\"preserve\">\n    <value>高对比度</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"HolographicAudio\" xml:space=\"preserve\">\n    <value>全息音频</value>\n  </data>\n  <data name=\"HolographicEnvironment\" xml:space=\"preserve\">\n    <value>全息环境</value>\n  </data>\n  <data name=\"HolographicHeadset\" xml:space=\"preserve\">\n    <value>全息头显</value>\n  </data>\n  <data name=\"HolographicManagement\" xml:space=\"preserve\">\n    <value>全息管理</value>\n  </data>\n  <data name=\"HomeGroup\" xml:space=\"preserve\">\n    <value>家庭组</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Id\" xml:space=\"preserve\">\n    <value>ID</value>\n    <comment>MEans The \"Windows Identifier\"</comment>\n  </data>\n  <data name=\"Image\" xml:space=\"preserve\">\n    <value>图像</value>\n  </data>\n  <data name=\"IndexingOptions\" xml:space=\"preserve\">\n    <value>索引选项</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"inetcpl.cpl\" xml:space=\"preserve\">\n    <value>inetcpl.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Infrared\" xml:space=\"preserve\">\n    <value>红外线</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"InkingAndTyping\" xml:space=\"preserve\">\n    <value>墨迹书写和键入个性化</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"InternetOptions\" xml:space=\"preserve\">\n    <value>Internet 属性</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"intl.cpl\" xml:space=\"preserve\">\n    <value>intl.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"InvertedColors\" xml:space=\"preserve\">\n    <value>反色</value>\n  </data>\n  <data name=\"Ip\" xml:space=\"preserve\">\n    <value>IP</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"IpSecurityMonitor\" xml:space=\"preserve\">\n    <value>IP 安全监视器</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"IpSecurityPoliciesOnLocalComputer\" xml:space=\"preserve\">\n    <value>本地计算机上的 IP 安全策略</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"irprops.cpl\" xml:space=\"preserve\">\n    <value>irprops.cpl</value>\n  </data>\n  <data name=\"IsolatedBrowsing\" xml:space=\"preserve\">\n    <value>隔离浏览</value>\n  </data>\n  <data name=\"JapanImeSettings\" xml:space=\"preserve\">\n    <value>日语输入法（Japan IME）</value>\n    <comment>Area TimeAndLanguage, available if the Microsoft Japan input method editor is installed</comment>\n  </data>\n  <data name=\"joy.cpl\" xml:space=\"preserve\">\n    <value>joy.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"JoystickProperties\" xml:space=\"preserve\">\n    <value>游戏控制器属性</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"jpnime\" xml:space=\"preserve\">\n    <value>jpnime</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"Keyboard\" xml:space=\"preserve\">\n    <value>键盘</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"Keypad\" xml:space=\"preserve\">\n    <value>数字小键盘</value>\n  </data>\n  <data name=\"Keys\" xml:space=\"preserve\">\n    <value>按键</value>\n  </data>\n  <data name=\"Language\" xml:space=\"preserve\">\n    <value>语言</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"LightColor\" xml:space=\"preserve\">\n    <value>浅色</value>\n  </data>\n  <data name=\"LightMode\" xml:space=\"preserve\">\n    <value>浅色模式</value>\n  </data>\n  <data name=\"LocalGroupPolicy\" xml:space=\"preserve\">\n    <value>本地计算机策略</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"LocalUsersAndGroups\" xml:space=\"preserve\">\n    <value>本地用户和组</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"Location\" xml:space=\"preserve\">\n    <value>位置</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"LockScreen\" xml:space=\"preserve\">\n    <value>锁屏界面</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"Magnifier\" xml:space=\"preserve\">\n    <value>放大镜</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"MailMicrosoftExchangeOrWindowsMessaging\" xml:space=\"preserve\">\n    <value>电子邮件 - Microsoft Exchange 或 Windows Messaging</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"main.cpl\" xml:space=\"preserve\">\n    <value>main.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"ManageDevices\" xml:space=\"preserve\">\n    <value>管理设备</value>\n  </data>\n  <data name=\"ManageKnownNetworks\" xml:space=\"preserve\">\n    <value>管理已知网络</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"ManageOptionalFeatures\" xml:space=\"preserve\">\n    <value>管理可选功能</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"MBR\" xml:space=\"preserve\">\n    <value>MBR</value>\n  </data>\n  <data name=\"Messaging\" xml:space=\"preserve\">\n    <value>消息</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"MeteredConnection\" xml:space=\"preserve\">\n    <value>按流量计费的连接</value>\n  </data>\n  <data name=\"Microphone\" xml:space=\"preserve\">\n    <value>麦克风</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"MicrosoftMailPostOffice\" xml:space=\"preserve\">\n    <value>Microsoft 邮局</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"mlcfg32.cpl\" xml:space=\"preserve\">\n    <value>mlcfg32.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"MMC_azman\" xml:space=\"preserve\">\n    <value>azman.msc</value>\n  </data>\n  <data name=\"MMC_certlm\" xml:space=\"preserve\">\n    <value>certlm.msc</value>\n  </data>\n  <data name=\"MMC_certmgr\" xml:space=\"preserve\">\n    <value>certmgr.msc</value>\n  </data>\n  <data name=\"MMC_comexp\" xml:space=\"preserve\">\n    <value>comexp.msc</value>\n  </data>\n  <data name=\"MMC_compmgmt\" xml:space=\"preserve\">\n    <value>compmgmt.msc</value>\n  </data>\n  <data name=\"MMC_devmgmt\" xml:space=\"preserve\">\n    <value>devmgmt.msc</value>\n  </data>\n  <data name=\"MMC_diskmgmt\" xml:space=\"preserve\">\n    <value>diskmgmt.msc</value>\n  </data>\n  <data name=\"MMC_eventvwr\" xml:space=\"preserve\">\n    <value>eventvwr.msc</value>\n  </data>\n  <data name=\"MMC_fsmgmt\" xml:space=\"preserve\">\n    <value>fsmgmt.msc</value>\n  </data>\n  <data name=\"MMC_gpedit\" xml:space=\"preserve\">\n    <value>gpedit.msc</value>\n  </data>\n  <data name=\"MMC_lusrmgr\" xml:space=\"preserve\">\n    <value>lusrmgr.msc</value>\n  </data>\n  <data name=\"MMC_mmcexe\" xml:space=\"preserve\">\n    <value>mmc.exe</value>\n  </data>\n  <data name=\"MMC_perfmon\" xml:space=\"preserve\">\n    <value>perfmon.msc</value>\n  </data>\n  <data name=\"MMC_printmanagement\" xml:space=\"preserve\">\n    <value>printmanagement.msc</value>\n  </data>\n  <data name=\"MMC_rsop\" xml:space=\"preserve\">\n    <value>rsop.msc</value>\n  </data>\n  <data name=\"MMC_secpol\" xml:space=\"preserve\">\n    <value>secpol.msc</value>\n  </data>\n  <data name=\"MMC_services\" xml:space=\"preserve\">\n    <value>services.msc</value>\n  </data>\n  <data name=\"MMC_taskschd\" xml:space=\"preserve\">\n    <value>taskschd.msc</value>\n  </data>\n  <data name=\"MMC_tpm\" xml:space=\"preserve\">\n    <value>tpm.msc</value>\n  </data>\n  <data name=\"MMC_wf\" xml:space=\"preserve\">\n    <value>WF.msc</value>\n  </data>\n  <data name=\"MMC_wmimgmt\" xml:space=\"preserve\">\n    <value>WmiMgmt.msc</value>\n  </data>\n  <data name=\"mmsys.cpl\" xml:space=\"preserve\">\n    <value>mmsys.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"MobileDevices\" xml:space=\"preserve\">\n    <value>移动设备</value>\n  </data>\n  <data name=\"MobileHotspot\" xml:space=\"preserve\">\n    <value>移动热点</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"modem.cpl\" xml:space=\"preserve\">\n    <value>modem.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Mono\" xml:space=\"preserve\">\n    <value>单声道音频</value>\n  </data>\n  <data name=\"MoreDetails\" xml:space=\"preserve\">\n    <value>更多详细信息</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"Motion\" xml:space=\"preserve\">\n    <value>动作</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"Mouse\" xml:space=\"preserve\">\n    <value>鼠标</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"MouseAndTouchpad\" xml:space=\"preserve\">\n    <value>鼠标和触摸板</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"MouseFontsKeyboardAndPrintersProperties\" xml:space=\"preserve\">\n    <value>鼠标、字体、键盘及打印机属性</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"MousePointer\" xml:space=\"preserve\">\n    <value>光标和指针大小</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"MultimediaProperties\" xml:space=\"preserve\">\n    <value>多媒体选项</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Multitasking\" xml:space=\"preserve\">\n    <value>多任务处理</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"Narrator\" xml:space=\"preserve\">\n    <value>讲述人</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"NavigationBar\" xml:space=\"preserve\">\n    <value>导航栏</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"ncpa.cpl\" xml:space=\"preserve\">\n    <value>ncpa.cpl</value>\n  </data>\n  <data name=\"NearbyShareSettings\" xml:space=\"preserve\">\n    <value>就近共享设置</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"netcpl.cpl\" xml:space=\"preserve\">\n    <value>netcpl.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"netsetup.cpl\" xml:space=\"preserve\">\n    <value>netsetup.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Network\" xml:space=\"preserve\">\n    <value>网络</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"NetworkAndSharingCenter\" xml:space=\"preserve\">\n    <value>网络和共享中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"NetworkConnection\" xml:space=\"preserve\">\n    <value>网络连接</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"NetworkProperties\" xml:space=\"preserve\">\n    <value>网络属性</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"NetworkSessions\" xml:space=\"preserve\">\n    <value>网络会话</value>\n  </data>\n  <data name=\"NetworkSetupWizard\" xml:space=\"preserve\">\n    <value>网络设置向导</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"NetworkStatus\" xml:space=\"preserve\">\n    <value>网络状态</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"NFC\" xml:space=\"preserve\">\n    <value>NFC</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"NFCTransactions\" xml:space=\"preserve\">\n    <value>NFC 支付</value>\n    <comment>\"NFC should not translated\"</comment>\n  </data>\n  <data name=\"NightLight\" xml:space=\"preserve\">\n    <value>夜间模式</value>\n  </data>\n  <data name=\"NightLightSettings\" xml:space=\"preserve\">\n    <value>夜间模式设置</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"Note\" xml:space=\"preserve\">\n    <value>注意</value>\n  </data>\n  <data name=\"NoteAddYourPhone\" xml:space=\"preserve\">\n    <value>仅当您将移动设备连接到您的设备时可用。</value>\n  </data>\n  <data name=\"NoteAdvancedGraphics\" xml:space=\"preserve\">\n    <value>仅在支持高级图形选项的设备上可用。</value>\n  </data>\n  <data name=\"NoteBattery\" xml:space=\"preserve\">\n    <value>仅适用于配备电池的设备，例如平板电脑。</value>\n  </data>\n  <data name=\"NoteDeprecated17763\" xml:space=\"preserve\">\n    <value>在 Windows 10 版本 1809（内部版本 17763）及更高版本中已弃用。</value>\n  </data>\n  <data name=\"NoteDialPaired\" xml:space=\"preserve\">\n    <value>仅当 Dial 已配对时可用。</value>\n  </data>\n  <data name=\"NoteDirectAccess\" xml:space=\"preserve\">\n    <value>仅当 DirectAccess 启用时可用。</value>\n  </data>\n  <data name=\"NoteDisplayGraphics\" xml:space=\"preserve\">\n    <value>仅在支持高级显示选项的设备上可用。</value>\n  </data>\n  <data name=\"NoteEditingRequireAdminPrivileges\" xml:space=\"preserve\">\n    <value>编辑此设置需要管理员权限。</value>\n  </data>\n  <data name=\"NoteEnrolledWIP\" xml:space=\"preserve\">\n    <value>仅当用户注册 WIP 时出现。</value>\n  </data>\n  <data name=\"NoteEyetrackerHardware\" xml:space=\"preserve\">\n    <value>需要目视跟踪设备。</value>\n  </data>\n  <data name=\"NoteImeJapan\" xml:space=\"preserve\">\n    <value>仅在安装了微软日语输入法后可用。</value>\n  </data>\n  <data name=\"NoteImePinyin\" xml:space=\"preserve\">\n    <value>仅在安装了微软拼音输入法后可用。</value>\n  </data>\n  <data name=\"NoteImeWubi\" xml:space=\"preserve\">\n    <value>仅在安装了微软五笔输入法后可用。</value>\n  </data>\n  <data name=\"NoteMixedReality\" xml:space=\"preserve\">\n    <value>仅在安装了混合现实门户应用程序后可用。</value>\n  </data>\n  <data name=\"NoteMobileProvisioning\" xml:space=\"preserve\">\n    <value>仅在企业已部署预配包的移动设备上可用。</value>\n  </data>\n  <data name=\"NoteNoMscFileExist\" xml:space=\"preserve\">\n    <value>此管理单元需要手动添加。</value>\n  </data>\n  <data name=\"NoteSince18362\" xml:space=\"preserve\">\n    <value>在 Windows 10 版本 1903（内部版本 18362）中加入。</value>\n  </data>\n  <data name=\"NoteSince19041\" xml:space=\"preserve\">\n    <value>在 Windows 10 版本 2004（内部版本 19041）中加入。</value>\n  </data>\n  <data name=\"NoteThirdParty\" xml:space=\"preserve\">\n    <value>仅当安装了第三方设置应用时可用。</value>\n  </data>\n  <data name=\"NoteTouchpad\" xml:space=\"preserve\">\n    <value>仅当存在触摸板硬件时可用。</value>\n  </data>\n  <data name=\"NoteWiFiAdapter\" xml:space=\"preserve\">\n    <value>仅当设备具有 Wi-Fi 适配器时可用。</value>\n  </data>\n  <data name=\"NoteWindowsAnywhere\" xml:space=\"preserve\">\n    <value>设备必须支持 Windows Anywhere。</value>\n  </data>\n  <data name=\"NoteWorkplaceProvisioning\" xml:space=\"preserve\">\n    <value>仅在企业已部署预配包时可用。</value>\n  </data>\n  <data name=\"Notifications\" xml:space=\"preserve\">\n    <value>通知</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"NotificationsAndActions\" xml:space=\"preserve\">\n    <value>通知和操作</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"NumLock\" xml:space=\"preserve\">\n    <value>数字锁定键 NumLock</value>\n    <comment>Mean the \"Num Lock\" key</comment>\n  </data>\n  <data name=\"nwc.cpl\" xml:space=\"preserve\">\n    <value>nwc.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"odbccp32.cpl\" xml:space=\"preserve\">\n    <value>odbccp32.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"OdbcDataSourceAdministrator32Bit\" xml:space=\"preserve\">\n    <value>ODBC 数据源管理程序 (32 位)</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"OdbcDataSourceAdministrator64Bit\" xml:space=\"preserve\">\n    <value>ODBC 数据源管理程序 (64 位)</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"OfflineFiles\" xml:space=\"preserve\">\n    <value>脱机文件</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"OfflineMaps\" xml:space=\"preserve\">\n    <value>离线地图</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"OfflineMapsDownloadMaps\" xml:space=\"preserve\">\n    <value>离线地图 - 下载地图</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"OnScreen\" xml:space=\"preserve\">\n    <value>屏幕键盘</value>\n  </data>\n  <data name=\"OpenControlPanel\" xml:space=\"preserve\">\n    <value>控制面板主页</value>\n    <comment>'Control Panel' is here the name of the legacy settings app.</comment>\n  </data>\n  <data name=\"OpenSettingsApp\" xml:space=\"preserve\">\n    <value>设置主页</value>\n    <comment>'Settings' is here the name of the modern settings app.</comment>\n  </data>\n  <data name=\"Os\" xml:space=\"preserve\">\n    <value>OS</value>\n    <comment>Means the \"Operating System\"</comment>\n  </data>\n  <data name=\"OtherDevices\" xml:space=\"preserve\">\n    <value>其他设备</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"OtherOptions\" xml:space=\"preserve\">\n    <value>其他选项</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"OtherUsers\" xml:space=\"preserve\">\n    <value>其他用户</value>\n  </data>\n  <data name=\"ParentalControls\" xml:space=\"preserve\">\n    <value>家长控制</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Password\" xml:space=\"preserve\">\n    <value>密码</value>\n  </data>\n  <data name=\"password.cpl\" xml:space=\"preserve\">\n    <value>password.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"PasswordProperties\" xml:space=\"preserve\">\n    <value>密码属性</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PenAndInputDevices\" xml:space=\"preserve\">\n    <value>笔和输入设备</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PenAndTouch\" xml:space=\"preserve\">\n    <value>笔和触控</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PenAndWindowsInk\" xml:space=\"preserve\">\n    <value>笔和 Windows Ink</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"PeopleNearMe\" xml:space=\"preserve\">\n    <value>网络邻居</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PerformanceInformationAndTools\" xml:space=\"preserve\">\n    <value>性能信息和工具</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PerformanceMonitor\" xml:space=\"preserve\">\n    <value>性能监视器</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"PermissionsAndHistory\" xml:space=\"preserve\">\n    <value>权限和历史记录</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"PersonalizationCategory\" xml:space=\"preserve\">\n    <value>个性化（类别）</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"Phone\" xml:space=\"preserve\">\n    <value>手机</value>\n    <comment>Area Phone</comment>\n  </data>\n  <data name=\"PhoneAndModem\" xml:space=\"preserve\">\n    <value>电话和调制解调器</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PhoneAndModemOptions\" xml:space=\"preserve\">\n    <value>电话和调制解调器 - 选项</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PhoneCalls\" xml:space=\"preserve\">\n    <value>电话呼叫</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"PhoneDefaultApps\" xml:space=\"preserve\">\n    <value>手机 - 默认应用</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"PhoneLink\" xml:space=\"preserve\">\n    <value>手机连接</value>\n  </data>\n  <data name=\"Picture\" xml:space=\"preserve\">\n    <value>图片</value>\n  </data>\n  <data name=\"Pictures\" xml:space=\"preserve\">\n    <value>图片</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"PinyinImeSettings\" xml:space=\"preserve\">\n    <value>微软拼音输入法设置</value>\n    <comment>Area TimeAndLanguage, available if the Microsoft Pinyin input method editor is installed</comment>\n  </data>\n  <data name=\"PinyinImeSettingsDomainLexicon\" xml:space=\"preserve\">\n    <value>微软拼音输入法设置 - 专业词典</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"PinyinImeSettingsKeyConfiguration\" xml:space=\"preserve\">\n    <value>微软拼音输入法设置 - 按键</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"PinyinImeSettingsUdp\" xml:space=\"preserve\">\n    <value>微软拼音输入法设置 - 用户自定义短语</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"PlayingGameFullScreen\" xml:space=\"preserve\">\n    <value>当我玩游戏时</value>\n    <comment>Area Gaming</comment>\n  </data>\n  <data name=\"PluginDescription\" xml:space=\"preserve\">\n    <value>搜索 Windows 设置</value>\n\t<comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"PluginTitle\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"PnpDevice\" xml:space=\"preserve\">\n    <value>PNP 设备</value>\n  </data>\n  <data name=\"PowerAndSleep\" xml:space=\"preserve\">\n    <value>电源和睡眠</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"powercfg.cpl\" xml:space=\"preserve\">\n    <value>powercfg.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"PowerOptions\" xml:space=\"preserve\">\n    <value>电源选项</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Presentation\" xml:space=\"preserve\">\n    <value>演示</value>\n  </data>\n  <data name=\"Printers\" xml:space=\"preserve\">\n    <value>打印机</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"PrintersAndScanners\" xml:space=\"preserve\">\n    <value>打印机和扫描仪</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"PrinterSpooler\" xml:space=\"preserve\">\n    <value>打印后台处理服务</value>\n  </data>\n  <data name=\"PrintManagement\" xml:space=\"preserve\">\n    <value>打印管理</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"PrintScreen\" xml:space=\"preserve\">\n    <value>截图键 PrintScreen</value>\n    <comment>Mean the \"Print screen\" key</comment>\n  </data>\n  <data name=\"ProblemReportsAndSolutions\" xml:space=\"preserve\">\n    <value>问题报告和解决方案</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Processor\" xml:space=\"preserve\">\n    <value>处理器</value>\n  </data>\n  <data name=\"ProgramsAndFeatures\" xml:space=\"preserve\">\n    <value>程序和功能</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"ProjectingToThisPc\" xml:space=\"preserve\">\n    <value>投影到此电脑</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"protanopia\" xml:space=\"preserve\">\n    <value>红色盲</value>\n    <comment>Medical: Mean you don't can see green colors</comment>\n  </data>\n  <data name=\"Provisioning\" xml:space=\"preserve\">\n    <value>预配置</value>\n    <comment>Area UserAccounts, only available if enterprise has deployed a provisioning package</comment>\n  </data>\n  <data name=\"Proximity\" xml:space=\"preserve\">\n    <value>飞行模式</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"Proxy\" xml:space=\"preserve\">\n    <value>代理</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"Quickime\" xml:space=\"preserve\">\n    <value>速成输入法</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"QuietMomentsGame\" xml:space=\"preserve\">\n    <value>游戏专注时刻</value>\n  </data>\n  <data name=\"Radios\" xml:space=\"preserve\">\n    <value>无线收发器</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"Ram\" xml:space=\"preserve\">\n    <value>内存</value>\n    <comment>Means the Read-Access-Memory (typical the used to inform about the size)</comment>\n  </data>\n  <data name=\"Recognition\" xml:space=\"preserve\">\n    <value>语音识别</value>\n  </data>\n  <data name=\"Recovery\" xml:space=\"preserve\">\n    <value>恢复</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"RedEye\" xml:space=\"preserve\">\n    <value>红眼疲劳</value>\n    <comment>Mean red eye effect by over-the-night flights</comment>\n  </data>\n  <data name=\"RedGreen\" xml:space=\"preserve\">\n    <value>红绿色</value>\n    <comment>Mean the weakness you can't differ between red and green colors</comment>\n  </data>\n  <data name=\"RedWeek\" xml:space=\"preserve\">\n    <value>红色弱</value>\n    <comment>Mean you don't can see red colors</comment>\n  </data>\n  <data name=\"Region\" xml:space=\"preserve\">\n    <value>区域</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"RegionalLanguage\" xml:space=\"preserve\">\n    <value>区域语言</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"RegionalSettingsProperties\" xml:space=\"preserve\">\n    <value>区域属性</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"RegionAndLanguage\" xml:space=\"preserve\">\n    <value>区域和语言</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"RegionFormatting\" xml:space=\"preserve\">\n    <value>区域格式</value>\n  </data>\n  <data name=\"RemoteAppAndDesktopConnections\" xml:space=\"preserve\">\n    <value>RemoteApp 和桌面连接</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"RemoteDesktop\" xml:space=\"preserve\">\n    <value>远程桌面</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"RemovePrograms\" xml:space=\"preserve\">\n    <value>删除程序</value>\n  </data>\n  <data name=\"RepairPrograms\" xml:space=\"preserve\">\n    <value>修复程序</value>\n  </data>\n  <data name=\"ResultantSetOfPolicy\" xml:space=\"preserve\">\n    <value>策略的结果集</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"ScannersAndCameras\" xml:space=\"preserve\">\n    <value>扫描仪和照相机</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"schedtasks\" xml:space=\"preserve\">\n    <value>schedtasks</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Scheduled\" xml:space=\"preserve\">\n    <value>计划任务</value>\n  </data>\n  <data name=\"ScheduledTasks\" xml:space=\"preserve\">\n    <value>任务计划程序</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"ScreenRotation\" xml:space=\"preserve\">\n    <value>屏幕旋转</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"ScreenSaver\" xml:space=\"preserve\">\n    <value>屏幕保护程序</value>\n  </data>\n  <data name=\"ScrollBars\" xml:space=\"preserve\">\n    <value>滚动条</value>\n  </data>\n  <data name=\"ScrollLock\" xml:space=\"preserve\">\n    <value>滚动锁定键 ScrollLock</value>\n    <comment>Mean the \"Scroll Lock\" key</comment>\n  </data>\n  <data name=\"Sdns\" xml:space=\"preserve\">\n    <value>SDNS</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"SearchingWindows\" xml:space=\"preserve\">\n    <value>搜索 Windows</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"SecureDNS\" xml:space=\"preserve\">\n    <value>SecureDNS</value>\n    <comment>Should not translated</comment>\n  </data>\n  <data name=\"SecurityCenter\" xml:space=\"preserve\">\n    <value>安全中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"SecurityConfigurationAndAnalysis\" xml:space=\"preserve\">\n    <value>安全配置和分析</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"SecurityProcessor\" xml:space=\"preserve\">\n    <value>安全处理器</value>\n  </data>\n  <data name=\"SecurityTemplates\" xml:space=\"preserve\">\n    <value>安全模板</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"ServicesSnapIn\" xml:space=\"preserve\">\n    <value>服务</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"SessionCleanup\" xml:space=\"preserve\">\n    <value>会话清理</value>\n    <comment>Area SurfaceHub</comment>\n  </data>\n  <data name=\"SettingsApp\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"SetUpKiosk\" xml:space=\"preserve\">\n    <value>设置展台</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"ShareAcrossDevices\" xml:space=\"preserve\">\n    <value>跨设备共享</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"SharedExperiences\" xml:space=\"preserve\">\n    <value>共享体验设置</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"SharedFolders\" xml:space=\"preserve\">\n    <value>共享文件夹</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"Shortcuts\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"ShortNameWiFi\" xml:space=\"preserve\">\n    <value>wifi</value>\n    <comment>dont translate this, is a short term to find entries</comment>\n  </data>\n  <data name=\"SignInOptions\" xml:space=\"preserve\">\n    <value>登录选项</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"SignInOptionsDynamicLock\" xml:space=\"preserve\">\n    <value>登录选项 - 动态锁</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"Size\" xml:space=\"preserve\">\n    <value>文本大小</value>\n    <comment>Size for text and symbols</comment>\n  </data>\n  <data name=\"SMB\" xml:space=\"preserve\">\n    <value>SMB</value>\n  </data>\n  <data name=\"Sound\" xml:space=\"preserve\">\n    <value>声音</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"Speech\" xml:space=\"preserve\">\n    <value>语音</value>\n    <comment>Area EaseOfAccess</comment>\n  </data>\n  <data name=\"SpeechRecognition\" xml:space=\"preserve\">\n    <value>语音识别</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"SpeechTyping\" xml:space=\"preserve\">\n    <value>语音输入</value>\n  </data>\n  <data name=\"Start\" xml:space=\"preserve\">\n    <value>开始</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"StartPlaces\" xml:space=\"preserve\">\n    <value>开始菜单</value>\n  </data>\n  <data name=\"StartupApps\" xml:space=\"preserve\">\n    <value>启动应用</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"sticpl.cpl\" xml:space=\"preserve\">\n    <value>sticpl.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Storage\" xml:space=\"preserve\">\n    <value>存储</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"StoragePolicies\" xml:space=\"preserve\">\n    <value>存储策略</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"StorageSense\" xml:space=\"preserve\">\n    <value>存储感知</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"SyncCenter\" xml:space=\"preserve\">\n    <value>同步中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"SyncYourSettings\" xml:space=\"preserve\">\n    <value>同步你的设置</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"sysdm.cpl\" xml:space=\"preserve\">\n    <value>sysdm.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"System\" xml:space=\"preserve\">\n    <value>系统</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"SystemEnvVars\" xml:space=\"preserve\">\n    <value>系统环境变量 (System env vars)</value>\n    <comment>Short english form. Don't translate!</comment>\n  </data>\n  <data name=\"SystemPropertiesAndAddNewHardwareWizard\" xml:space=\"preserve\">\n    <value>系统属性/添加新硬件向导</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"SystemTools\" xml:space=\"preserve\">\n    <value>系统工具</value>\n  </data>\n  <data name=\"SystemVariables\" xml:space=\"preserve\">\n    <value>系统变量</value>\n  </data>\n  <data name=\"Tab\" xml:space=\"preserve\">\n    <value>Tab</value>\n    <comment>Means the key \"Tabulator\" on the keyboard</comment>\n  </data>\n  <data name=\"TabletMode\" xml:space=\"preserve\">\n    <value>平板模式</value>\n    <comment>Area System</comment>\n  </data>\n  <data name=\"TabletPC.cpl\" xml:space=\"preserve\">\n    <value>TabletPC.cpl</value>\n  </data>\n  <data name=\"TabletPcSettings\" xml:space=\"preserve\">\n    <value>平板电脑设置</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Talk\" xml:space=\"preserve\">\n    <value>说话</value>\n  </data>\n  <data name=\"TalkToCortana\" xml:space=\"preserve\">\n    <value>对 Cortana 说话</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"Taskbar\" xml:space=\"preserve\">\n    <value>任务栏</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"TaskbarColor\" xml:space=\"preserve\">\n    <value>任务栏颜色</value>\n  </data>\n  <data name=\"Tasks\" xml:space=\"preserve\">\n    <value>任务</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"TaskScheduler\" xml:space=\"preserve\">\n    <value>任务计划程序</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"TeamConferencing\" xml:space=\"preserve\">\n    <value>团队会议</value>\n    <comment>Area SurfaceHub</comment>\n  </data>\n  <data name=\"TeamDeviceManagement\" xml:space=\"preserve\">\n    <value>团队设备管理</value>\n    <comment>Area SurfaceHub</comment>\n  </data>\n  <data name=\"telephon.cpl\" xml:space=\"preserve\">\n    <value>telephon.cpl</value>\n  </data>\n  <data name=\"TextToSpeech\" xml:space=\"preserve\">\n    <value>文本到语音转换</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"Themes\" xml:space=\"preserve\">\n    <value>主题</value>\n    <comment>Area Personalization</comment>\n  </data>\n  <data name=\"themes.cpl\" xml:space=\"preserve\">\n    <value>themes.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"timedate.cpl\" xml:space=\"preserve\">\n    <value>timedate.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Timeline\" xml:space=\"preserve\">\n    <value>时间线</value>\n  </data>\n  <data name=\"Timeout\" xml:space=\"preserve\">\n    <value>超时</value>\n  </data>\n  <data name=\"Touch\" xml:space=\"preserve\">\n    <value>触摸</value>\n  </data>\n  <data name=\"TouchFeedback\" xml:space=\"preserve\">\n    <value>触摸反馈</value>\n  </data>\n  <data name=\"Touchpad\" xml:space=\"preserve\">\n    <value>触摸板</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"TpmManagement\" xml:space=\"preserve\">\n    <value>TPM 管理</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"Transparency\" xml:space=\"preserve\">\n    <value>透明效果</value>\n  </data>\n  <data name=\"tritanopia\" xml:space=\"preserve\">\n    <value>蓝色盲</value>\n    <comment>Medical: Mean you don't can see yellow and blue colors</comment>\n  </data>\n  <data name=\"Troubleshoot\" xml:space=\"preserve\">\n    <value>疑难解答</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"TruePlay\" xml:space=\"preserve\">\n    <value>TruePlay</value>\n    <comment>Area Gaming</comment>\n  </data>\n  <data name=\"TurnScreenSaverOnOff\" xml:space=\"preserve\">\n    <value>开启或关闭屏保</value>\n  </data>\n  <data name=\"Typing\" xml:space=\"preserve\">\n    <value>输入</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"UAC\" xml:space=\"preserve\">\n    <value>UAC</value>\n    <comment>Short version of 'User account control'</comment>\n  </data>\n  <data name=\"Uninstall\" xml:space=\"preserve\">\n    <value>卸载</value>\n    <comment>Area MixedReality, only available if the Mixed Reality Portal app is installed.</comment>\n  </data>\n  <data name=\"UninstallPrograms\" xml:space=\"preserve\">\n    <value>卸载程序</value>\n  </data>\n  <data name=\"Usb\" xml:space=\"preserve\">\n    <value>USB</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"UserAccountControlSettings.exe\" xml:space=\"preserve\">\n    <value>UserAccountControlSettings.exe</value>\n    <comment>Name of the executable</comment>\n  </data>\n  <data name=\"UserAccounts\" xml:space=\"preserve\">\n    <value>用户帐户</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"UserEnvironmentVariables\" xml:space=\"preserve\">\n    <value>帐户的环境变量</value>\n  </data>\n  <data name=\"UserEnvVars\" xml:space=\"preserve\">\n    <value>用户环境变量 (User env vars)</value>\n    <comment>Short english form. Don't translate!</comment>\n  </data>\n  <data name=\"UserVariables\" xml:space=\"preserve\">\n    <value>用户变量</value>\n  </data>\n  <data name=\"Version\" xml:space=\"preserve\">\n    <value>版本</value>\n    <comment>Means The \"Windows Version\"</comment>\n  </data>\n  <data name=\"VideoPlayback\" xml:space=\"preserve\">\n    <value>视频播放</value>\n    <comment>Area Apps</comment>\n  </data>\n  <data name=\"Videos\" xml:space=\"preserve\">\n    <value>视频</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"VirtualDesktops\" xml:space=\"preserve\">\n    <value>虚拟桌面</value>\n  </data>\n  <data name=\"Virus\" xml:space=\"preserve\">\n    <value>病毒</value>\n    <comment>Means the virus in computers and software</comment>\n  </data>\n  <data name=\"VoiceActivation\" xml:space=\"preserve\">\n    <value>语音激活</value>\n    <comment>Area Privacy</comment>\n  </data>\n  <data name=\"Volume\" xml:space=\"preserve\">\n    <value>音量</value>\n  </data>\n  <data name=\"Vpn\" xml:space=\"preserve\">\n    <value>VPN</value>\n    <comment>Area NetworkAndInternet</comment>\n  </data>\n  <data name=\"Wallpaper\" xml:space=\"preserve\">\n    <value>壁纸</value>\n  </data>\n  <data name=\"WarmerColor\" xml:space=\"preserve\">\n    <value>暖色</value>\n  </data>\n  <data name=\"WelcomeCenter\" xml:space=\"preserve\">\n    <value>欢迎中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"WelcomeScreen\" xml:space=\"preserve\">\n    <value>欢迎屏幕</value>\n    <comment>Area SurfaceHub</comment>\n  </data>\n  <data name=\"wgpocpl.cpl\" xml:space=\"preserve\">\n    <value>wgpocpl.cpl</value>\n    <comment>File name, Should not translated</comment>\n  </data>\n  <data name=\"Wheel\" xml:space=\"preserve\">\n    <value>滚轮</value>\n    <comment>Area Device</comment>\n  </data>\n  <data name=\"WiFi\" xml:space=\"preserve\">\n    <value>Wi-Fi</value>\n    <comment>Area NetworkAndInternet, only available if Wi-Fi calling is enabled</comment>\n  </data>\n  <data name=\"WiFiCalling\" xml:space=\"preserve\">\n    <value>Wi-Fi 通话</value>\n    <comment>Area NetworkAndInternet, only available if Wi-Fi calling is enabled</comment>\n  </data>\n  <data name=\"WiFiSettings\" xml:space=\"preserve\">\n    <value>Wi-Fi 设置</value>\n    <comment>\"Wi-Fi\" should not translated</comment>\n  </data>\n  <data name=\"WindowBorder\" xml:space=\"preserve\">\n    <value>窗口边框</value>\n  </data>\n  <data name=\"WindowsAnytimeUpgrade\" xml:space=\"preserve\">\n    <value>Windows Anytime Upgrade</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"WindowsAnywhere\" xml:space=\"preserve\">\n    <value>Windows Anywhere</value>\n    <comment>Area UserAccounts, device must be Windows Anywhere-capable</comment>\n  </data>\n  <data name=\"WindowsCardSpace\" xml:space=\"preserve\">\n    <value>Windows CardSpace</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"WindowsDefender\" xml:space=\"preserve\">\n    <value>Windows Defender</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"WindowsFirewall\" xml:space=\"preserve\">\n    <value>Windows 防火墙</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"WindowsHelloSetupFace\" xml:space=\"preserve\">\n    <value>Windows Hello 安装程序 - 面部识别</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"WindowsHelloSetupFingerprint\" xml:space=\"preserve\">\n    <value>Windows Hello 安装程序 - 指纹识别</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"WindowsInsiderProgram\" xml:space=\"preserve\">\n    <value>Windows 预览体验计划</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"WindowsManagementInstrumentation\" xml:space=\"preserve\">\n    <value>Windows Management Instrumentation</value>\n  </data>\n  <data name=\"WindowsMobilityCenter\" xml:space=\"preserve\">\n    <value>Windows 移动中心</value>\n    <comment>Area Control Panel (legacy settings)</comment>\n  </data>\n  <data name=\"WindowsSearch\" xml:space=\"preserve\">\n    <value>Windows 搜索</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"WindowsSearchSettings\" xml:space=\"preserve\">\n    <value>Windows 搜索设置</value>\n    <comment>Area Cortana</comment>\n  </data>\n  <data name=\"WindowsSecurity\" xml:space=\"preserve\">\n    <value>Windows 安全中心</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"WindowsUpdate\" xml:space=\"preserve\">\n    <value>Windows 更新</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"WindowsUpdateAdvancedOptions\" xml:space=\"preserve\">\n    <value>Windows 更新 - 高级选项</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"WindowsUpdateCheckForUpdates\" xml:space=\"preserve\">\n    <value>Windows 更新 - 检查更新</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"WindowsUpdateRestartOptions\" xml:space=\"preserve\">\n    <value>Windows 更新 - 计划重启</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"WindowsUpdateViewOptionalUpdates\" xml:space=\"preserve\">\n    <value>Windows 更新 - 查看可选更新</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"WindowsUpdateViewUpdateHistory\" xml:space=\"preserve\">\n    <value>Windows 更新 - 查看更新历史记录</value>\n    <comment>Area UpdateAndSecurity</comment>\n  </data>\n  <data name=\"Wireless\" xml:space=\"preserve\">\n    <value>无线网络</value>\n  </data>\n  <data name=\"WmiControl\" xml:space=\"preserve\">\n    <value>WMI 控件</value>\n    <comment>Name of MMC Snap-In.</comment>\n  </data>\n  <data name=\"Workplace\" xml:space=\"preserve\">\n    <value>工作区</value>\n  </data>\n  <data name=\"WorkplaceProvisioning\" xml:space=\"preserve\">\n    <value>工作区预配置</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"wscui.cpl\" xml:space=\"preserve\">\n    <value>wscui.cpl</value>\n  </data>\n  <data name=\"WubiImeSettings\" xml:space=\"preserve\">\n    <value>微软五笔输入法设置</value>\n    <comment>Area TimeAndLanguage, available if the Microsoft Wubi input method editor is installed</comment>\n  </data>\n  <data name=\"WubiImeSettingsUdp\" xml:space=\"preserve\">\n    <value>微软五笔输入法设置 - 用户自定义短语</value>\n    <comment>Area TimeAndLanguage</comment>\n  </data>\n  <data name=\"XboxNetworking\" xml:space=\"preserve\">\n    <value>Xbox 网络</value>\n    <comment>Area Gaming</comment>\n  </data>\n  <data name=\"YourInfo\" xml:space=\"preserve\">\n    <value>账户信息</value>\n    <comment>Area UserAccounts</comment>\n  </data>\n  <data name=\"Zoom\" xml:space=\"preserve\">\n    <value>放大</value>\n    <comment>Mean zooming of things via a magnifier</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Main.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\n\nusing Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Helpers;\nusing Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Properties;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Wox.Infrastructure;\nusing Wox.Plugin;\nusing Wox.Plugin.Logger;\n\nnamespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal\n{\n    public class Main : IPlugin, IContextMenu, IPluginI18n, ISettingProvider\n    {\n        private const string OpenNewTab = nameof(OpenNewTab);\n        private const string OpenQuake = nameof(OpenQuake);\n        private const string ShowHiddenProfiles = nameof(ShowHiddenProfiles);\n        private readonly TerminalQuery _terminalQuery = new TerminalQuery();\n        private PluginInitContext _context;\n        private bool _openNewTab;\n        private bool _openQuake;\n        private bool _showHiddenProfiles;\n        private Dictionary<string, BitmapImage> _logoCache = new Dictionary<string, BitmapImage>();\n\n        public string Name => Resources.plugin_name;\n\n        public string Description => Resources.plugin_description;\n\n        public static string PluginID => \"F59BA85006B14389A72A0EA756695F1D\";\n\n        public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>()\n        {\n            new PluginAdditionalOption()\n            {\n                Key = OpenNewTab,\n                DisplayLabel = Resources.open_new_tab,\n                Value = false,\n            },\n\n            new PluginAdditionalOption()\n            {\n                Key = OpenQuake,\n                DisplayLabel = Resources.open_quake,\n                DisplayDescription = Resources.open_quake_description,\n                Value = false,\n            },\n\n            new PluginAdditionalOption()\n            {\n                Key = ShowHiddenProfiles,\n                DisplayLabel = Resources.show_hidden_profiles,\n                Value = false,\n            },\n        };\n\n        public void Init(PluginInitContext context)\n        {\n            _context = context;\n        }\n\n        public List<Result> Query(Query query)\n        {\n            var search = query?.Search ?? string.Empty;\n            var profiles = _terminalQuery.GetProfiles();\n\n            var result = new List<Result>();\n\n            foreach (var profile in profiles)\n            {\n                if (profile.Hidden && !_showHiddenProfiles)\n                {\n                    continue;\n                }\n\n                // Action keyword only or search query match\n                int score = StringMatcher.FuzzySearch(search, profile.Name).Score;\n                if (string.IsNullOrWhiteSpace(search) || score > 0)\n                {\n                    result.Add(new Result\n                    {\n                        Title = profile.Name,\n                        SubTitle = profile.Terminal.DisplayName,\n                        Icon = () => GetLogo(profile.Terminal),\n                        Score = score,\n                        Action = _ =>\n                        {\n                            Launch(profile.Terminal.AppUserModelId, profile.Name);\n                            return true;\n                        },\n                        ContextData = profile,\n                    });\n                }\n            }\n\n            return result;\n        }\n\n        public List<ContextMenuResult> LoadContextMenus(Result selectedResult)\n        {\n            if (!(selectedResult?.ContextData is TerminalProfile))\n            {\n                return new List<ContextMenuResult>();\n            }\n\n            var result = new List<ContextMenuResult>();\n\n            if (selectedResult.ContextData is TerminalProfile profile)\n            {\n                result.Add(new ContextMenuResult\n                {\n                    Title = Resources.run_as_administrator,\n                    Glyph = \"\\xE7EF\",\n                    FontFamily = \"Segoe Fluent Icons,Segoe MDL2 Assets\",\n                    AcceleratorKey = Key.Enter,\n                    AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,\n                    Action = _ =>\n                    {\n                        LaunchElevated(profile.Terminal.AppUserModelId, profile.Name);\n                        return true;\n                    },\n                });\n            }\n\n            return result;\n        }\n\n        public string GetTranslatedPluginTitle()\n        {\n            return Resources.plugin_name;\n        }\n\n        public string GetTranslatedPluginDescription()\n        {\n            return Resources.plugin_description;\n        }\n\n        private void Launch(string id, string profile)\n        {\n            var appManager = new ApplicationActivationManager();\n            const ActivateOptions noFlags = ActivateOptions.None;\n            var queryArguments = TerminalHelper.GetArguments(profile, _openNewTab, _openQuake);\n            try\n            {\n                appManager.ActivateApplication(id, queryArguments, noFlags, out var unusedPid);\n            }\n            catch (Exception ex)\n            {\n                var name = \"插件: \" + Resources.plugin_name;\n                var message = Resources.run_terminal_failed;\n                Log.Exception(\"Failed to open Windows Terminal\", ex, GetType());\n                _context.API.ShowMsg(name, message, string.Empty);\n            }\n        }\n\n        private void LaunchElevated(string id, string profile)\n        {\n            try\n            {\n                string path = \"shell:AppsFolder\\\\\" + id;\n                Helper.OpenInShell(path, TerminalHelper.GetArguments(profile, _openNewTab, _openQuake), runAs: Helper.ShellRunAsType.Administrator);\n            }\n            catch (Exception ex)\n            {\n                var name = \"插件: \" + Resources.plugin_name;\n                var message = Resources.run_terminal_failed;\n                Log.Exception(\"Failed to open Windows Terminal\", ex, GetType());\n                _context.API.ShowMsg(name, message, string.Empty);\n            }\n        }\n\n        public Control CreateSettingPanel()\n        {\n            throw new NotImplementedException();\n        }\n\n        public void UpdateSettings(PowerLauncherPluginSettings settings)\n        {\n            var openNewTab = false;\n            var openQuake = false;\n            var showHiddenProfiles = false;\n\n            if (settings != null && settings.AdditionalOptions != null)\n            {\n                openNewTab = settings.AdditionalOptions.FirstOrDefault(x => x.Key == OpenNewTab)?.Value ?? false;\n                openQuake = settings.AdditionalOptions.FirstOrDefault(x => x.Key == OpenQuake)?.Value ?? false;\n                showHiddenProfiles = settings.AdditionalOptions.FirstOrDefault(x => x.Key == ShowHiddenProfiles)?.Value ?? false;\n            }\n\n            _openNewTab = openNewTab;\n            _openQuake = openQuake;\n            _showHiddenProfiles = showHiddenProfiles;\n        }\n\n        private BitmapImage GetLogo(TerminalPackage terminal)\n        {\n            var aumid = terminal.AppUserModelId;\n\n            if (!_logoCache.TryGetValue(aumid, out BitmapImage value))\n            {\n                value = terminal.GetLogo();\n                _logoCache.Add(aumid, value);\n            }\n\n            return value;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"open_new_tab\" xml:space=\"preserve\">\n    <value>在新标签页打开配置文件</value>\n  </data>\n  <data name=\"open_quake\" xml:space=\"preserve\">\n    <value>在下拉栏中打开配置文件</value>\n    <comment>Quake is a well-known computer game. Don't localize. See https://en.wikipedia.org/wiki/Quake_(video_game)</comment>\n  </data>\n  <data name=\"open_quake_description\" xml:space=\"preserve\">\n    <value>下拉栏，又名 Quake 模式，即上半屏分屏显示控制台窗口，可以按快捷键打开</value>\n    <comment>Quake is a well-known computer game. Don't localize. See https://en.wikipedia.org/wiki/Quake_(video_game)；；Zetaspace：Not at my country.</comment>\n  </data>\n  <data name=\"plugin_description\" xml:space=\"preserve\">\n    <value>打开 Windows Terminal 配置文件</value>\n  </data>\n  <data name=\"plugin_name\" xml:space=\"preserve\">\n    <value>Windows Terminal</value>\n  </data>\n  <data name=\"run_as_administrator\" xml:space=\"preserve\">\n    <value>以管理员权限运行(Ctrl+Shift+Enter)</value>\n  </data>\n  <data name=\"run_terminal_failed\" xml:space=\"preserve\">\n    <value>无法打开 Windows Terminal</value>\n  </data>\n  <data name=\"show_hidden_profiles\" xml:space=\"preserve\">\n    <value>显示隐藏配置文件</value>\n  </data>\n</root>\n"
  },
  {
    "path": "PowerToys/src/modules/launcher/PowerLauncher/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"startTyping\" xml:space=\"preserve\">\n    <value>搜点什么...</value>\n  </data>\n  <data name=\"registerHotkeyFailed\" xml:space=\"preserve\">\n    <value>注册快捷键失败：{0}</value>\n  </data>\n  <data name=\"executeQuery\" xml:space=\"preserve\">\n    <value>执行查询：{0}</value>\n  </data>\n  <data name=\"lastExecuteTime\" xml:space=\"preserve\">\n    <value>上次运行时间：{0}</value>\n  </data>\n  <data name=\"reportWindow_header\" xml:space=\"preserve\">\n    <value>出现了一些问题。</value>\n  </data>\n  <data name=\"reportWindow_file_bug\" xml:space=\"preserve\">\n    <value>请汇报这个问题，发送到</value>\n    <comment>reportWindow_file_bug + reportWindow_github_repo string</comment>\n  </data>\n  <data name=\"reportWindow_github_repo\" xml:space=\"preserve\">\n    <value>PowerToys GitHub 仓库</value>\n    <comment>reportWindow_file_bug + reportWindow_github_repo string</comment>\n  </data>\n  <data name=\"reportWindow_upload_log\" xml:space=\"preserve\">\n    <value>请上传日志文件和错误信息。</value>\n  </data>\n  <data name=\"reportWindow_period\" xml:space=\"preserve\">\n    <value>.</value>\n  </data>\n  <data name=\"reportWindow_wox_got_an_error\" xml:space=\"preserve\">\n    <value>PowerToys 启动器遇到问题</value>\n  </data>\n  <data name=\"AppIcon\" xml:space=\"preserve\">\n    <value>应用图标</value>\n  </data>\n  <data name=\"ContextMenuItem\" xml:space=\"preserve\">\n    <value>上下文菜单项</value>\n  </data>\n  <data name=\"ContextMenuItemAdditionalInformation\" xml:space=\"preserve\">\n    <value>上下文菜单项附加信息</value>\n  </data>\n  <data name=\"ContextMenuIcon\" xml:space=\"preserve\">\n    <value>上下文菜单图标</value>\n  </data>\n  <data name=\"ContextMenuItemsCollection\" xml:space=\"preserve\">\n    <value>上下文菜单项集</value>\n  </data>\n  <data name=\"Query\" xml:space=\"preserve\">\n    <value>查询</value>\n  </data>\n  <data name=\"Results\" xml:space=\"preserve\">\n    <value>结果</value>\n  </data>\n  <data name=\"SearchIcon\" xml:space=\"preserve\">\n    <value>搜索图标</value>\n  </data>\n  <data name=\"Subtitle\" xml:space=\"preserve\">\n    <value>子标题</value>\n  </data>\n  <data name=\"Title\" xml:space=\"preserve\">\n    <value>标题</value>\n  </data>\n  <data name=\"deserialization_error_title\" xml:space=\"preserve\">\n    <value>PowerToys 启动器反序列化错误</value>\n  </data>\n  <data name=\"deserialization_error_message\" xml:space=\"preserve\">\n    <value>设置将被重置为默认值，程序仍将继续运行。</value>\n  </data>\n  <data name=\"FailedToInitializePluginsDescription\" xml:space=\"preserve\">\n    <value>无法加载插件: {0}</value>\n  </data>\n  <data name=\"FailedToInitializePluginsTitle\" xml:space=\"preserve\">\n    <value>PowerToys 启动器 - 插件初始化失败</value>\n    <comment>Don't translate \"PowerToys Run\". This is a product name.</comment>\n  </data>\n  <data name=\"ContextMenuItemsAvailable\" xml:space=\"preserve\">\n    <value>控制按钮可用</value>\n  </data>\n  <data name=\"PluginKeywords\" xml:space=\"preserve\">\n    <value>插件关键字</value>\n  </data>\n  <data name=\"RegisterHotkeyFailedTitle\" xml:space=\"preserve\">\n    <value>PowerToys 启动器 - 快捷键错误</value>\n    <comment>Don't translate \"PowerToys Run\". This is a product name.</comment>\n  </data>\n  <data name=\"FailedToInitializePluginsDescriptionPartTwo\" xml:space=\"preserve\">\n    <value>请将问题汇报到 https://aka.ms/powerToysReportBug。（第三方插件请联系插件作者）</value>\n    <comment>\"https://aka.ms/powerToysReportBug\" is a web uri.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/peek/Peek.UI/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"AppTitle.Title\" xml:space=\"preserve\">\n    <value>快速查看</value>\n    <comment>Name of application.</comment>\n  </data>\n  <data name=\"AppTitle_FileCounts_Text\" xml:space=\"preserve\">\n    <value>({0}/{1})</value>\n    <comment>Text for the file count in the title bar. 0: the index of the current file. 1: the total number of files selected.</comment>\n  </data>\n  <data name=\"LaunchAppButton_OpenWith_Text\" xml:space=\"preserve\">\n    <value>打开方式</value>\n    <comment>Text for button to launch the application picker.</comment>\n  </data>\n  <data name=\"LaunchAppButton_OpenWith_ToolTip\" xml:space=\"preserve\">\n    <value>打开方式 (回车)</value>\n    <comment>Tooltip for button to launch the application picker.</comment>\n  </data>\n  <data name=\"LaunchAppButton_OpenWithApp_Text\" xml:space=\"preserve\">\n    <value>用 {0} 打开</value>\n    <comment>Text for button to launch default application. 0: name of the default application.</comment>\n  </data>\n  <data name=\"LaunchAppButton_OpenWithApp_ToolTip\" xml:space=\"preserve\">\n    <value>用 {0} 打开 (回车)</value>\n    <comment>Tooltip for button to launch default application. 0: name of the default application.</comment>\n  </data>\n  <data name=\"UnsupportedFile_FileType\" xml:space=\"preserve\">\n    <value>类型: {0}</value>\n    <comment>File Type label for the unsupported files view. {0} is the type.</comment>\n  </data>\n  <data name=\"UnsupportedFile_FileSize\" xml:space=\"preserve\">\n    <value>大小: {0}</value>\n    <comment>File Size label for the unsupported files view. {0} is the size.</comment>\n  </data>\n  <data name=\"UnsupportedFile_DateModified\" xml:space=\"preserve\">\n    <value>日期: {0}</value>\n    <comment>Date Modified label for the unsupported files view. {0} is the date.</comment>\n  </data>\n  <data name=\"ReadableString_ByteAbbreviationFormat\" xml:space=\"preserve\">\n    <value>B</value>\n    <comment>Abbreviation for the size unit byte.</comment>\n  </data>\n  <data name=\"ReadableString_KiloByteAbbreviationFormat\" xml:space=\"preserve\">\n    <value>KB</value>\n    <comment>Abbreviation for the size unit kilobyte.</comment>\n  </data>\n  <data name=\"ReadableString_MegaByteAbbreviationFormat\" xml:space=\"preserve\">\n    <value>MB</value>\n    <comment>Abbreviation for the size unit megabyte.</comment>\n  </data>\n  <data name=\"ReadableString_GigaByteAbbreviationFormat\" xml:space=\"preserve\">\n    <value>GB</value>\n    <comment>Abbreviation for the size unit gigabyte.</comment>\n  </data>\n  <data name=\"ReadableString_TeraByteAbbreviationFormat\" xml:space=\"preserve\">\n    <value>TB</value>\n    <comment>Abbreviation for the size unit terabyte.</comment>\n  </data>\n  <data name=\"ReadableString_PetaByteAbbreviationFormat\" xml:space=\"preserve\">\n    <value>PB</value>\n    <comment>Abbreviation for the size unit petabyte.</comment>\n  </data>\n  <data name=\"ReadableString_ExaByteAbbreviationFormat\" xml:space=\"preserve\">\n    <value>EB</value>\n    <comment>Abbreviation for the size unit exabyte.</comment>\n  </data>\n  <data name=\"PreviewTooltip_FileName\" xml:space=\"preserve\">\n    <value>名称: {0}</value>\n    <comment>Filename for the tooltip of preview. {0} is the name.</comment>\n  </data>\n  <data name=\"PreviewTooltip_FileType\" xml:space=\"preserve\">\n    <value>类型: {0}</value>\n    <comment>Item Type for the tooltip of preview. {0} is the type.</comment>\n  </data>\n  <data name=\"PreviewTooltip_DateModified\" xml:space=\"preserve\">\n    <value>日期: {0}</value>\n    <comment>Date Modified label for the tooltip of preview. {0} is the date.</comment>\n  </data>\n  <data name=\"PreviewTooltip_Dimensions\" xml:space=\"preserve\">\n    <value>尺寸: {0} × {1}</value>\n    <comment>Dimensions label for the tooltip of preview. {0} is the width, {1} is the height.</comment>\n  </data>\n  <data name=\"PreviewTooltip_FileSize\" xml:space=\"preserve\">\n    <value>大小: {0}</value>\n    <comment>File Size label for the tooltip of preview. {0} is the size.</comment>\n  </data>\n  <data name=\"PreviewTooltip_Blank\" xml:space=\"preserve\">\n    <value>快速查看文件</value>\n    <comment>Tooltip of preview when there's no file info available.</comment>\n  </data>\n  <data name=\"PinButton_Tooltip\" xml:space=\"preserve\">\n    <value>固定当前窗口大小</value>\n    <comment>Tooltip for button to pin the Peek window.</comment>\n  </data>\n  <data name=\"UnpinButton_ToolTip\" xml:space=\"preserve\">\n    <value>取消固定窗口大小</value>\n    <comment>Tooltip for button to unpin the Peek window.</comment>\n  </data>\n  <data name=\"FailedFallbackReportBugHyperlinkButton.Content\" xml:space=\"preserve\">\n    <value>反馈问题</value>\n    <comment>Failed fallback preview Report bug hyperlink button content.</comment>\n  </data>\n  <data name=\"FailedFallbackTextBlock.Text\" xml:space=\"preserve\">\n    <value>无法查看此文件</value>\n    <comment>Failed fallback preview text.</comment>\n  </data>\n  <data name=\"Archive_Directory_Count\" xml:space=\"preserve\">\n    <value>{0} 个目录</value>\n    <comment>{0} is the number of directories in the archive</comment>\n  </data>\n  <data name=\"Archive_File_Count\" xml:space=\"preserve\">\n    <value>{0} 个文件</value>\n    <comment>{0} is the number of files in the archive</comment>\n  </data>\n  <data name=\"Archive_Size\" xml:space=\"preserve\">\n    <value>{0} (解压后 {1})</value>\n    <comment>{0} is the size of the archive, {1} is the extracted size</comment>\n  </data>\n  <data name=\"ReadableString_BytesAbbreviationFormat\" xml:space=\"preserve\">\n    <value>B</value>\n    <comment>Abbreviation for the size bytes</comment>\n  </data>\n  <data name=\"OpenUriDialog.CloseButtonText\" xml:space=\"preserve\">\n    <value>取消</value>\n    <comment>Dialog showed when an URI is clicked. Button to close the dialog.</comment>\n  </data>\n  <data name=\"OpenUriDialog.PrimaryButtonText\" xml:space=\"preserve\">\n    <value>打开</value>\n    <comment>Dialog showed when an URI is clicked. Button to open the URI.</comment>\n  </data>\n  <data name=\"OpenUriDialog.SecondaryButtonText\" xml:space=\"preserve\">\n    <value>复制</value>\n    <comment>Dialog showed when an URI is clicked. Button to copy the URI.</comment>\n  </data>\n  <data name=\"OpenUriDialog.Title\" xml:space=\"preserve\">\n    <value>确定要使用软件来打开吗？</value>\n    <comment>Title of the dialog showed when an URI is clicked,\"Peek\" is the name of the utility. </comment>\n  </data>\n  <data name=\"ReadableString_BytesString\" xml:space=\"preserve\">\n    <value> ({1:N0} B)</value>\n    <comment>Displays total number of bytes. Don't localize the \"{1:N0}\" part.</comment>\n  </data>\n  <data name=\"ReadableString_ByteString\" xml:space=\"preserve\">\n    <value> ({1:N0} B)</value>\n    <comment>Displays unit byte. Don't localize the \"{1:N0}\" part.</comment>\n  </data>\n  <data name=\"WindowTitle\" xml:space=\"preserve\">\n    <value>{0} - 快速查看</value>\n    <comment>Title of the Peek window. {0} is the name of the currently previewed item.\"Peek\" is the name of the utility.</comment>\n  </data>\n  <data name=\"Drive_FreeSpace\" xml:space=\"preserve\">\n    <value>{0} 可用</value>\n    <comment>{0} is the free space of the drive</comment>\n  </data>\n  <data name=\"Drive_UsedSpace\" xml:space=\"preserve\">\n    <value>{0} 已用</value>\n    <comment>{0} is the used space of the drive</comment>\n  </data>\n  <data name=\"Drive_Capacity\" xml:space=\"preserve\">\n    <value>容量: {0}</value>\n    <comment>{0} is the capacity of the drive</comment>\n  </data>\n  <data name=\"Drive_FileSystem\" xml:space=\"preserve\">\n    <value>文件系统: {0}</value>\n    <comment>{0} is the file system of the drive</comment>\n  </data>\n  <data name=\"Drive_Type\" xml:space=\"preserve\">\n    <value>类型: {0}</value>\n    <comment>{0} is the type of the drive</comment>\n  </data>\n  <data name=\"Drive_Type_Fixed\" xml:space=\"preserve\">\n    <value>固定</value>\n  </data>\n  <data name=\"Drive_Type_Network\" xml:space=\"preserve\">\n    <value>网络</value>\n  </data>\n  <data name=\"Drive_Type_Optical\" xml:space=\"preserve\">\n    <value>光盘</value>\n    <comment>\"Optical\" indicates CD or DVD drives</comment>\n  </data>\n  <data name=\"Drive_Type_RAM_Disk\" xml:space=\"preserve\">\n    <value>内存盘</value>\n  </data>\n  <data name=\"Drive_Type_Removable\" xml:space=\"preserve\">\n    <value>可移动</value>\n    <comment>\"Removal\" indicates USB or external hard drives</comment>\n  </data>\n  <data name=\"Drive_Unknown\" xml:space=\"preserve\">\n    <value>未知</value>\n    <comment>Used for unknown drive type or file system</comment>\n  </data>\n  <data name=\"Audio_Album\" xml:space=\"preserve\">\n    <value>专辑: {0}</value>\n    <comment>{0} is the title of the album read from file metadata</comment>\n  </data>\n  <data name=\"Audio_Artist\" xml:space=\"preserve\">\n    <value>歌手: {0}</value>\n    <comment>{0} is the artist read from file metadata</comment>\n  </data>\n  <data name=\"Audio_Length\" xml:space=\"preserve\">\n    <value>时长: {0}</value>\n    <comment>{0} is the duration of the audio read from file metadata</comment>\n  </data>\n  <data name=\"ContextMenu_Copy\" xml:space=\"preserve\">\n    <value>复制</value>\n    <comment>Copy selected text to clipboard</comment>\n  </data>\n  <data name=\"ContextMenu_ToggleTextWrapping\" xml:space=\"preserve\">\n    <value>切换自动换行</value>\n    <comment>Toggle whether text in pane is word-wrapped</comment>\n  </data>\n  <data name=\"ContextMenu_ToggleMinimap\" xml:space=\"preserve\">\n    <value>切换小地图</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/powerrename/PowerRenameContextMenu/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"PowerRename_App_Name\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>do not loc, product name</comment>\n  </data>\n  <data name=\"PowerRename_Context_Menu_Entry\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>PowerRename is a product name. do not loc it</comment>\n  </data>\n</root>\n"
  },
  {
    "path": "PowerToys/src/modules/powerrename/PowerRenameUILib/PowerRenameXAML/MainWindow.xaml.cpp",
    "content": "﻿#include \"pch.h\"\n#include \"MainWindow.xaml.h\"\n#if __has_include(\"MainWindow.g.cpp\")\n#include \"MainWindow.g.cpp\"\n#endif\n\n#include <settings.h>\n#include <trace.h>\n\n#include <common/logger/call_tracer.h>\n#include <common/logger/logger.h>\n#include <common/utils/logger_helper.h>\n#include <common/utils/process_path.h>\n\n#include <common/Telemetry/EtwTrace/EtwTrace.h>\n\n#include <atlstr.h>\n#include <exception>\n#include <string>\n#include <sstream>\n#include <vector>\n#include <shellscalingapi.h>\n\n#include \"microsoft.ui.xaml.window.h\"\n#include <winrt/Microsoft.UI.Interop.h>\n#include <winrt/Windows.UI.ViewManagement.h>\n#include <winrt/Microsoft.UI.Windowing.h>\n#include <common/Themes/theme_helpers.h>\n#include <common/Themes/theme_listener.h>\n\nusing namespace winrt;\nusing namespace Windows::UI::Xaml;\nusing namespace winrt::Microsoft::Windows::ApplicationModel::Resources;\n// Non-localizable\nconst std::wstring PowerRenameUIIco = L\"PowerRenameUI.ico\";\nconst wchar_t c_WindowClass[] = L\"PowerRename\";\nHINSTANCE g_hostHInst;\n\nextern std::vector<std::wstring> g_files;\n\n// Theming\nThemeListener theme_listener{};\nHWND CurrentWindow;\n\nvoid handleTheme()\n{\n    auto theme = theme_listener.AppTheme;\n    auto isDark = theme == Theme::Dark;\n    Logger::info(L\"Theme is now {}\", isDark ? L\"Dark\" : L\"Light\");\n    ThemeHelpers::SetImmersiveDarkMode(CurrentWindow, isDark);\n}\n\n// Disabled for now, because it causes indentation and icons to appear \"asynchronously\"\n// #define ENABLE_RECYCLING_VIRTUALIZATION_MODE\n\nCComPtr<IPowerRenameManager> g_prManager;\nstd::function<void(void)> g_itemToggledCallback;\n\nwinrt::Microsoft::UI::Xaml::Controls::ScrollViewer FindScrollViewer(winrt::Microsoft::UI::Xaml::DependencyObject start)\n{\n    int childrenCount = winrt::Microsoft::UI::Xaml::Media::VisualTreeHelper::GetChildrenCount(start);\n    for (int i = 0; i < childrenCount; i++)\n    {\n        auto obj = winrt::Microsoft::UI::Xaml::Media::VisualTreeHelper::GetChild(start, i);\n\n        if (auto sv = obj.try_as<winrt::Microsoft::UI::Xaml::Controls::ScrollViewer>())\n        {\n            return sv;\n        }\n        else\n        {\n            auto result = FindScrollViewer(obj);\n            if (result)\n            {\n                return result;\n            }\n        }\n    }\n    return nullptr;\n}\n\nPowerRenameUI::ExplorerItem FindFirstExplorerItemRecursive(winrt::Microsoft::UI::Xaml::DependencyObject startNode)\n{\n    auto explorerItem = startNode.try_as<PowerRenameUI::ExplorerItem>();\n    if (explorerItem)\n    {\n        return explorerItem;\n    }\n\n    int childCount = winrt::Microsoft::UI::Xaml::Media::VisualTreeHelper::GetChildrenCount(startNode);\n    for (int i = 0; i < childCount; ++i)\n    {\n        auto child = winrt::Microsoft::UI::Xaml::Media::VisualTreeHelper::GetChild(startNode, i);\n        explorerItem = FindFirstExplorerItemRecursive(child);\n        if (explorerItem)\n        {\n            return explorerItem;\n        }\n    }\n\n    return nullptr;\n}\n\nnamespace winrt::PowerRenameUI::implementation\n{\n    MainWindow::MainWindow() :\n        m_allSelected{ true }, m_managerEvents{ this }\n    {\n        Trace::RegisterProvider();\n\n        auto windowNative{ this->try_as<::IWindowNative>() };\n        winrt::check_bool(windowNative);\n        windowNative->get_WindowHandle(&m_window);\n        CurrentWindow = m_window;\n\n        // Attach theme handling\n        theme_listener.AddChangedHandler(handleTheme);\n        handleTheme();\n\n        Microsoft::UI::WindowId windowId =\n            Microsoft::UI::GetWindowIdFromWindow(m_window);\n\n        Microsoft::UI::Windowing::AppWindow appWindow =\n            Microsoft::UI::Windowing::AppWindow::GetFromWindowId(windowId);\n        appWindow.SetIcon(PowerRenameUIIco);\n\n        POINT cursorPosition{};\n        if (GetCursorPos(&cursorPosition))\n        {\n            ::Windows::Graphics::PointInt32 point{ cursorPosition.x, cursorPosition.y };\n            Microsoft::UI::Windowing::DisplayArea displayArea = Microsoft::UI::Windowing::DisplayArea::GetFromPoint(point, Microsoft::UI::Windowing::DisplayAreaFallback::Nearest);\n\n            HMONITOR hMonitor = MonitorFromPoint(cursorPosition, MONITOR_DEFAULTTOPRIMARY);\n            MONITORINFOEX monitorInfo;\n            monitorInfo.cbSize = sizeof(MONITORINFOEX);\n            GetMonitorInfo(hMonitor, &monitorInfo);\n            UINT x_dpi;\n            GetDpiForMonitor(hMonitor, MONITOR_DPI_TYPE::MDT_EFFECTIVE_DPI, &x_dpi, &x_dpi);\n            UINT window_dpi = GetDpiForWindow(m_window);\n\n            const auto& [width, height] = LastRunSettingsInstance().GetLastWindowSize();\n\n            winrt::Windows::Graphics::RectInt32 rect;\n            // Scale window size\n            rect.Width = static_cast<int32_t>(width * static_cast<float>(window_dpi) / x_dpi);\n            rect.Height = static_cast<int32_t>(height * static_cast<float>(window_dpi) / x_dpi);\n            // Center to screen\n            rect.X = displayArea.WorkArea().X + displayArea.WorkArea().Width / 2 - width / 2;\n            rect.Y = displayArea.WorkArea().Y + displayArea.WorkArea().Height / 2 - height / 2;\n\n            appWindow.MoveAndResize(rect);\n        }\n\n        Title(hstring{ L\"批量重命名\" });\n\n        m_searchMRUList = winrt::single_threaded_observable_vector<hstring>();\n        m_replaceMRUList = winrt::single_threaded_observable_vector<hstring>();\n\n        std::function<void(void)> toggledCallback = [this] {\n            _TRACER_;\n            UpdateCounts();\n        };\n\n        g_itemToggledCallback.swap(toggledCallback);\n\n        m_explorerItems = winrt::make<ExplorerItemsSource>();\n        get_self<ExplorerItemsSource>(m_explorerItems)->SetIsFiltered(false);\n\n        m_searchRegExShortcuts = winrt::single_threaded_observable_vector<PowerRenameUI::PatternSnippet>();\n        auto factory = winrt::get_activation_factory<ResourceManager, IResourceManagerFactory>();\n        ResourceManager manager = factory.CreateInstance(L\"PowerToys.PowerRename.pri\");\n\n        m_searchRegExShortcuts.Append(winrt::make<PatternSnippet>(L\".\", manager.MainResourceMap().GetValue(L\"Resources/RegExCheatSheet_MatchAny\").ValueAsString()));\n        m_searchRegExShortcuts.Append(winrt::make<PatternSnippet>(L\"\\\\d\", manager.MainResourceMap().GetValue(L\"Resources/RegExCheatSheet_MatchDigit\").ValueAsString()));\n        m_searchRegExShortcuts.Append(winrt::make<PatternSnippet>(L\"\\\\D\", manager.MainResourceMap().GetValue(L\"Resources/RegExCheatSheet_MatchNonDigit\").ValueAsString()));\n        m_searchRegExShortcuts.Append(winrt::make<PatternSnippet>(L\"\\\\w\", manager.MainResourceMap().GetValue(L\"Resources/RegExCheatSheet_MatchWordChar\").ValueAsString()));\n        m_searchRegExShortcuts.Append(winrt::make<PatternSnippet>(L\"\\\\S\", manager.MainResourceMap().GetValue(L\"Resources/RegExCheatSheet_MatchNonWS\").ValueAsString()));\n        m_searchRegExShortcuts.Append(winrt::make<PatternSnippet>(L\"\\\\S+\", manager.MainResourceMap().GetValue(L\"Resources/RegExCheatSheet_MatchOneOrMoreWS\").ValueAsString()));\n        m_searchRegExShortcuts.Append(winrt::make<PatternSnippet>(L\"\\\\b\", manager.MainResourceMap().GetValue(L\"Resources/RegExCheatSheet_MatchWordBoundary\").ValueAsString()));\n\n        m_dateTimeShortcuts = winrt::single_threaded_observable_vector<PowerRenameUI::PatternSnippet>();\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$YYYY\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_FullYear\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$YY\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_YearLastTwoDigits\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$Y\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_YearLastDigit\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$MMMM\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MonthName\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$MMM\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MonthNameAbbr\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$MM\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MonthDigitLZero\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$M\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MonthDigit\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$DDDD\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_DayName\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$DDD\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_DayNameAbbr\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$DD\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_DayDigitLZero\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$D\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_DayDigit\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$hh\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_HoursLZero\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$h\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_Hours\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$mm\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MinutesLZero\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$m\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_Minutes\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$ss\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_SecondsLZero\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$s\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_Seconds\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$fff\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MilliSeconds3D\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$ff\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MilliSeconds2D\").ValueAsString()));\n        m_dateTimeShortcuts.Append(winrt::make<PatternSnippet>(L\"$f\", manager.MainResourceMap().GetValue(L\"Resources/DateTimeCheatSheet_MilliSeconds1D\").ValueAsString()));\n\n        m_CounterShortcuts = winrt::single_threaded_observable_vector<PowerRenameUI::PatternSnippet>();\n        m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L\"${}\", manager.MainResourceMap().GetValue(L\"Resources/CounterCheatSheet_Simple\").ValueAsString()));\n        m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L\"${start=10}\", manager.MainResourceMap().GetValue(L\"Resources/CounterCheatSheet_Start\").ValueAsString()));\n        m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L\"${increment=5}\", manager.MainResourceMap().GetValue(L\"Resources/CounterCheatSheet_Increment\").ValueAsString()));\n        m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L\"${padding=8}\", manager.MainResourceMap().GetValue(L\"Resources/CounterCheatSheet_Padding\").ValueAsString()));\n        m_CounterShortcuts.Append(winrt::make<PatternSnippet>(L\"${increment=3,padding=4,start=900}\", manager.MainResourceMap().GetValue(L\"Resources/CounterCheatSheet_Complex\").ValueAsString()));\n\n        m_RandomizerShortcuts = winrt::single_threaded_observable_vector<PowerRenameUI::PatternSnippet>();\n        m_RandomizerShortcuts.Append(winrt::make<PatternSnippet>(L\"${rstringalnum=9}\", manager.MainResourceMap().GetValue(L\"Resources/RandomizerCheatSheet_Alnum\").ValueAsString()));\n        m_RandomizerShortcuts.Append(winrt::make<PatternSnippet>(L\"${rstringalpha=13}\", manager.MainResourceMap().GetValue(L\"Resources/RandomizerCheatSheet_Alpha\").ValueAsString()));\n        m_RandomizerShortcuts.Append(winrt::make<PatternSnippet>(L\"${rstringdigit=36}\", manager.MainResourceMap().GetValue(L\"Resources/RandomizerCheatSheet_Digit\").ValueAsString()));\n        m_RandomizerShortcuts.Append(winrt::make<PatternSnippet>(L\"${ruuidv4}\", manager.MainResourceMap().GetValue(L\"Resources/RandomizerCheatSheet_Uuid\").ValueAsString()));\n\n        InitializeComponent();\n\n        m_etwTrace.UpdateState(true);\n\n        listView_ExplorerItems().ApplyTemplate();\n#ifdef ENABLE_RECYCLING_VIRTUALIZATION_MODE\n        if (auto scrollViewer = FindScrollViewer(listView_ExplorerItems()); scrollViewer)\n        {\n            Microsoft::UI::Xaml::DispatcherTimer debounceTimer = nullptr;\n\n            scrollViewer.ViewChanged([this, scrollViewer, timer = std::move(debounceTimer)](IInspectable const&, Microsoft::UI::Xaml::Controls::ScrollViewerViewChangedEventArgs const&) mutable {\n                if (!timer)\n                {\n                    timer = {};\n                    timer.Tick([this, &timer](auto&, auto&) {\n                        get_self<ExplorerItemsSource>(m_explorerItems)->InvalidateCollection();\n                        timer.Stop();\n                        timer = nullptr;\n                    });\n                }\n\n                using namespace std::chrono_literals;\n\n                winrt::Windows::Foundation::TimeSpan timeSpan{ 200ms };\n                timer.Interval(timeSpan);\n                timer.Start();\n            });\n        }\n#endif\n        if (SUCCEEDED(CPowerRenameManager::s_CreateInstance(&m_prManager)))\n        {\n            g_prManager = m_prManager;\n            // Create the factory for our items\n            CComPtr<IPowerRenameItemFactory> prItemFactory;\n            if (SUCCEEDED(CPowerRenameItem::s_CreateInstance(nullptr, IID_PPV_ARGS(&prItemFactory))))\n            {\n                if (SUCCEEDED(m_prManager->PutRenameItemFactory(prItemFactory)))\n                {\n                    if (SUCCEEDED(m_prManager->Advise(&m_managerEvents, &m_cookie)))\n                    {\n                        CComPtr<IShellItemArray> shellItemArray;\n                        // To test PowerRename uncomment DEBUG_BENCHMARK_100K_ENTRIES define\n                        if (!g_files.empty())\n                        {\n                            if (SUCCEEDED(CreateShellItemArrayFromPaths(std::move(g_files), &shellItemArray)))\n                            {\n                                CComPtr<IEnumShellItems> enumShellItems;\n                                if (SUCCEEDED(shellItemArray->EnumItems(&enumShellItems)))\n                                {\n                                    EnumerateShellItems(enumShellItems);\n                                }\n                            }\n                        }\n                        else\n                        {\n                            Logger::warn(L\"No items selected to be renamed.\");\n                        }\n                    }\n                }\n            }\n            else\n            {\n                Logger::error(L\"Error creating PowerRenameItemFactory\");\n            }\n        }\n        else\n        {\n            Logger::error(L\"Error creating PowerRenameManager\");\n        }\n        try\n        {\n            UpdateCounts();\n            SetHandlers();\n            ReadSettings();\n        }\n        catch (std::exception& e)\n        {\n            Logger::error(\"Exception thrown during explorer items population: {}\", std::string{ e.what() });\n        }\n\n        button_rename().IsEnabled(false);\n        toggleButton_enumItems().IsChecked(true);\n        toggleButton_randItems().IsChecked(false);\n        InitAutoComplete();\n        SearchReplaceChanged();\n        InvalidateItemListViewState();\n\n        SizeChanged({ this, &MainWindow::OnSizeChanged });\n        Closed({ this, &MainWindow::OnClosed });\n    }\n\n    void MainWindow::OnSizeChanged(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::WindowSizeChangedEventArgs const& /*args*/)\n    {\n        const auto appWindow =\n            Microsoft::UI::Windowing::AppWindow::GetFromWindowId(Microsoft::UI::GetWindowIdFromWindow(m_window));\n        const auto [width, height] = appWindow.Size();\n\n        m_updatedWindowSize.emplace(std::make_pair(width, height));\n    }\n\n    void MainWindow::OnClosed(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::WindowEventArgs const&)\n    {\n        if (m_updatedWindowSize)\n        {\n            LastRunSettingsInstance().UpdateLastWindowSize(m_updatedWindowSize->first, m_updatedWindowSize->second);\n        }\n\n        m_etwTrace.Flush();\n        m_etwTrace.UpdateState(false);\n\n        Trace::UnregisterProvider();\n    }\n\n    void MainWindow::InvalidateItemListViewState()\n    {\n        get_self<ExplorerItemsSource>(m_explorerItems)->InvalidateCollection();\n    }\n\n    winrt::event_token MainWindow::PropertyChanged(Microsoft::UI::Xaml::Data::PropertyChangedEventHandler const& handler)\n    {\n        return m_propertyChanged.add(handler);\n    }\n\n    void MainWindow::PropertyChanged(winrt::event_token const& token) noexcept\n    {\n        m_propertyChanged.remove(token);\n    }\n\n    hstring MainWindow::OriginalCount()\n    {\n        UINT count = 0;\n        m_prManager->GetItemCount(&count);\n        return hstring{ std::to_wstring(count) };\n    }\n\n    void MainWindow::OriginalCount(hstring)\n    {\n        m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L\"OriginalCount\" });\n    }\n\n    hstring MainWindow::RenamedCount()\n    {\n        return hstring{ std::to_wstring(m_renamingCount) };\n    }\n\n    void MainWindow::RenamedCount(hstring)\n    {\n        m_propertyChanged(*this, Microsoft::UI::Xaml::Data::PropertyChangedEventArgs{ L\"RenamedCount\" });\n    }\n\n    void MainWindow::SelectAll(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)\n    {\n        if (checkBox_selectAll().IsChecked().GetBoolean() != m_allSelected)\n        {\n            ToggleAll();\n            m_allSelected = !m_allSelected;\n            if (button_showRenamed().IsChecked())\n            {\n                UpdateCounts();\n            }\n            InvalidateItemListViewState();\n        }\n    }\n\n    void MainWindow::ShowAll(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)\n    {\n        button_showAll().IsChecked(true);\n        button_showRenamed().IsChecked(false);\n\n        DWORD filter = 0;\n        m_prManager->GetFilter(&filter);\n        if (filter != PowerRenameFilters::None)\n        {\n            m_prManager->SwitchFilter(0);\n            get_self<ExplorerItemsSource>(m_explorerItems)->SetIsFiltered(false);\n            InvalidateItemListViewState();\n        }\n    }\n\n    void MainWindow::ShowRenamed(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)\n    {\n        button_showRenamed().IsChecked(true);\n        button_showAll().IsChecked(false);\n\n        DWORD filter = 0;\n        m_prManager->GetFilter(&filter);\n        if (filter != PowerRenameFilters::ShouldRename)\n        {\n            m_prManager->SwitchFilter(0);\n            UpdateCounts();\n            get_self<ExplorerItemsSource>(m_explorerItems)->SetIsFiltered(true);\n            InvalidateItemListViewState();\n        }\n    }\n\n    void MainWindow::RegExItemClick(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Controls::ItemClickEventArgs const& e)\n    {\n        auto s = e.ClickedItem().try_as<PatternSnippet>();\n        RegExFlyout().Hide();\n        textBox_search().Text(textBox_search().Text() + s->Code());\n    }\n\n    void MainWindow::DateTimeItemClick(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::Controls::ItemClickEventArgs const& e)\n    {\n        auto s = e.ClickedItem().try_as<PatternSnippet>();\n        DateTimeFlyout().Hide();\n        textBox_replace().Text(textBox_replace().Text() + s->Code());\n    }\n\n    void MainWindow::button_rename_Click(winrt::Microsoft::UI::Xaml::Controls::SplitButton const&, winrt::Microsoft::UI::Xaml::Controls::SplitButtonClickEventArgs const&)\n    {\n        Rename(false);\n    }\n\n    void MainWindow::MenuFlyoutItem_Click(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)\n    {\n        Rename(true);\n    }\n\n    void MainWindow::OpenDocs(winrt::Windows::Foundation::IInspectable const&, winrt::Microsoft::UI::Xaml::RoutedEventArgs const&)\n    {\n        Windows::System::Launcher::LaunchUriAsync(winrt::Windows::Foundation::Uri{ L\"https://aka.ms/PowerToysOverview_PowerRename\" });\n    }\n\n    HRESULT MainWindow::CreateShellItemArrayFromPaths(\n        std::vector<std::wstring> files,\n        IShellItemArray** shellItemArray)\n    {\n        _TRACER_;\n\n        *shellItemArray = nullptr;\n        PIDLIST_ABSOLUTE* itemList = nullptr;\n        itemList = new (std::nothrow) PIDLIST_ABSOLUTE[files.size()];\n        HRESULT hr = itemList ? S_OK : E_OUTOFMEMORY;\n        UINT itemsCnt = 0;\n        for (const auto& file : files)\n        {\n            const DWORD BUFSIZE = 4096;\n            TCHAR buffer[BUFSIZE] = TEXT(\"\");\n            auto retval = GetFullPathName(file.c_str(), BUFSIZE, buffer, NULL);\n            if (retval != 0 && PathFileExists(buffer))\n            {\n                hr = SHParseDisplayName(buffer, nullptr, &itemList[itemsCnt], 0, nullptr);\n                ++itemsCnt;\n            }\n        }\n        if (SUCCEEDED(hr) && itemsCnt > 0)\n        {\n            hr = SHCreateShellItemArrayFromIDLists(itemsCnt, const_cast<LPCITEMIDLIST*>(itemList), shellItemArray);\n            if (SUCCEEDED(hr))\n            {\n                for (UINT i = 0; i < itemsCnt; i++)\n                {\n                    CoTaskMemFree(itemList[i]);\n                }\n            }\n            else\n            {\n                Logger::error(L\"Creating ShellItemArray from path list failed.\");\n            }\n        }\n        else\n        {\n            Logger::error(L\"Parsing path list display names failed.\");\n            hr = E_FAIL;\n        }\n\n        delete[] itemList;\n        return hr;\n    }\n\n    HRESULT MainWindow::InitAutoComplete()\n    {\n        _TRACER_;\n\n        HRESULT hr = S_OK;\n        if (CSettingsInstance().GetMRUEnabled())\n        {\n            hr = CPowerRenameMRU::CPowerRenameMRUSearch_CreateInstance(&m_searchMRU);\n            if (SUCCEEDED(hr))\n            {\n                for (const auto& item : m_searchMRU->GetMRUStrings())\n                {\n                    if (!item.empty())\n                    {\n                        m_searchMRUList.Append(item);\n                    }\n                }\n            }\n\n            if (SUCCEEDED(hr))\n            {\n                hr = CPowerRenameMRU::CPowerRenameMRUReplace_CreateInstance(&m_replaceMRU);\n                if (SUCCEEDED(hr))\n                {\n                    for (const auto& item : m_replaceMRU->GetMRUStrings())\n                    {\n                        if (!item.empty())\n                        {\n                            m_replaceMRUList.Append(item);\n                        }\n                    }\n                }\n            }\n        }\n\n        return hr;\n    }\n\n    HRESULT MainWindow::EnumerateShellItems(_In_ IEnumShellItems* enumShellItems)\n    {\n        _TRACER_;\n\n        HRESULT hr = S_OK;\n        // Enumerate the data object and populate the manager\n        if (m_prManager)\n        {\n            m_disableCountUpdate = true;\n\n            // Ensure we re-create the enumerator\n            m_prEnum = nullptr;\n            hr = CPowerRenameEnum::s_CreateInstance(nullptr, m_prManager, IID_PPV_ARGS(&m_prEnum));\n            if (SUCCEEDED(hr))\n            {\n                hr = m_prEnum->Start(enumShellItems);\n            }\n\n            m_disableCountUpdate = false;\n        }\n\n        return hr;\n    }\n\n    void MainWindow::SearchReplaceChanged(bool forceRenaming)\n    {\n        _TRACER_;\n\n        Logger::debug(L\"Forced renaming - {}\", forceRenaming);\n        // Pass updated search and replace terms to the IPowerRenameRegEx handler\n        CComPtr<IPowerRenameRegEx> prRegEx;\n        if (m_prManager && SUCCEEDED(m_prManager->GetRenameRegEx(&prRegEx)))\n        {\n            winrt::hstring searchTerm = textBox_search().Text();\n            prRegEx->PutSearchTerm(searchTerm.c_str(), forceRenaming);\n\n            winrt::hstring replaceTerm = textBox_replace().Text();\n            prRegEx->PutReplaceTerm(replaceTerm.c_str(), forceRenaming);\n        }\n    }\n\n    void MainWindow::ValidateFlags(PowerRenameFlags flag)\n    {\n        if (flag == Uppercase)\n        {\n            if (toggleButton_upperCase().IsChecked())\n            {\n                toggleButton_lowerCase().IsChecked(false);\n                toggleButton_titleCase().IsChecked(false);\n                toggleButton_capitalize().IsChecked(false);\n            }\n        }\n        else if (flag == Lowercase)\n        {\n            if (toggleButton_lowerCase().IsChecked())\n            {\n                toggleButton_upperCase().IsChecked(false);\n                toggleButton_titleCase().IsChecked(false);\n                toggleButton_capitalize().IsChecked(false);\n            }\n        }\n        else if (flag == Titlecase)\n        {\n            if (toggleButton_titleCase().IsChecked())\n            {\n                toggleButton_upperCase().IsChecked(false);\n                toggleButton_lowerCase().IsChecked(false);\n                toggleButton_capitalize().IsChecked(false);\n            }\n        }\n        else if (flag == Capitalized)\n        {\n            if (toggleButton_capitalize().IsChecked())\n            {\n                toggleButton_upperCase().IsChecked(false);\n                toggleButton_lowerCase().IsChecked(false);\n                toggleButton_titleCase().IsChecked(false);\n            }\n        }\n\n        m_flagValidationInProgress = true;\n    }\n\n    void MainWindow::UpdateFlag(PowerRenameFlags flag, UpdateFlagCommand command)\n    {\n        _TRACER_;\n\n        DWORD flags{};\n        m_prManager->GetFlags(&flags);\n\n        if (command == UpdateFlagCommand::Set)\n        {\n            flags |= flag;\n        }\n        else if (command == UpdateFlagCommand::Reset)\n        {\n            flags &= ~flag;\n        }\n\n        Logger::debug(L\"Flag {} \" + std::wstring{ command == UpdateFlagCommand::Set ? L\"set\" : L\"reset\" }, flag);\n\n        // Ensure we update flags\n        if (m_prManager)\n        {\n            m_prManager->PutFlags(flags);\n        }\n\n        InvalidateItemListViewState();\n    }\n\n    void MainWindow::SetHandlers()\n    {\n        _TRACER_;\n\n        // AutoSuggestBox Search\n        textBox_search().TextChanged([&](auto const&, auto const&) {\n            SearchReplaceChanged();\n        });\n\n        // AutoSuggestBox Replace\n        textBox_replace().TextChanged([&](auto const&, auto const&) {\n            SearchReplaceChanged();\n        });\n\n        // ToggleButton UpperCase\n        toggleButton_upperCase().Checked([&](auto const&, auto const&) {\n            ValidateFlags(Uppercase);\n            UpdateFlag(Uppercase, UpdateFlagCommand::Set);\n        });\n        toggleButton_upperCase().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(Uppercase, UpdateFlagCommand::Reset);\n        });\n\n        // ToggleButton LowerCase\n        toggleButton_lowerCase().Checked([&](auto const&, auto const&) {\n            ValidateFlags(Lowercase);\n            UpdateFlag(Lowercase, UpdateFlagCommand::Set);\n        });\n        toggleButton_lowerCase().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(Lowercase, UpdateFlagCommand::Reset);\n        });\n\n        // ToggleButton TitleCase\n        toggleButton_titleCase().Checked([&](auto const&, auto const&) {\n            ValidateFlags(Titlecase);\n            UpdateFlag(Titlecase, UpdateFlagCommand::Set);\n        });\n        toggleButton_titleCase().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(Titlecase, UpdateFlagCommand::Reset);\n        });\n\n        // ToggleButton Capitalize\n        toggleButton_capitalize().Checked([&](auto const&, auto const&) {\n            ValidateFlags(Capitalized);\n            UpdateFlag(Capitalized, UpdateFlagCommand::Set);\n        });\n        toggleButton_capitalize().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(Capitalized, UpdateFlagCommand::Reset);\n        });\n\n        // CheckBox Regex\n        checkBox_regex().Checked([&](auto const&, auto const&) {\n            ValidateFlags(UseRegularExpressions);\n            UpdateFlag(UseRegularExpressions, UpdateFlagCommand::Set);\n        });\n        checkBox_regex().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(UseRegularExpressions, UpdateFlagCommand::Reset);\n        });\n\n        // CheckBox CaseSensitive\n        checkBox_case().Checked([&](auto const&, auto const&) {\n            ValidateFlags(CaseSensitive);\n            UpdateFlag(CaseSensitive, UpdateFlagCommand::Set);\n        });\n        checkBox_case().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(CaseSensitive, UpdateFlagCommand::Reset);\n        });\n\n        // ComboBox RenameParts\n        comboBox_renameParts().SelectionChanged([&](auto const&, auto const&) {\n            int selectedIndex = comboBox_renameParts().SelectedIndex();\n            if (selectedIndex == 0)\n            { // Filename + extension\n                UpdateFlag(NameOnly, UpdateFlagCommand::Reset);\n                UpdateFlag(ExtensionOnly, UpdateFlagCommand::Reset);\n            }\n            else if (selectedIndex == 1) // Filename Only\n            {\n                ValidateFlags(NameOnly);\n                UpdateFlag(ExtensionOnly, UpdateFlagCommand::Reset);\n                UpdateFlag(NameOnly, UpdateFlagCommand::Set);\n            }\n            else if (selectedIndex == 2) // Extension Only\n            {\n                ValidateFlags(ExtensionOnly);\n                UpdateFlag(NameOnly, UpdateFlagCommand::Reset);\n                UpdateFlag(ExtensionOnly, UpdateFlagCommand::Set);\n            }\n        });\n\n        // CheckBox MatchAllOccurrences\n        checkBox_matchAll().Checked([&](auto const&, auto const&) {\n            ValidateFlags(MatchAllOccurrences);\n            UpdateFlag(MatchAllOccurrences, UpdateFlagCommand::Set);\n        });\n        checkBox_matchAll().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(MatchAllOccurrences, UpdateFlagCommand::Reset);\n        });\n\n        // ToggleButton IncludeFiles\n        toggleButton_includeFiles().Checked([&](auto const&, auto const&) {\n            ValidateFlags(ExcludeFiles);\n            UpdateFlag(ExcludeFiles, UpdateFlagCommand::Reset);\n        });\n        toggleButton_includeFiles().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(ExcludeFiles, UpdateFlagCommand::Set);\n        });\n\n        // ToggleButton IncludeFolders\n        toggleButton_includeFolders().Checked([&](auto const&, auto const&) {\n            ValidateFlags(ExcludeFolders);\n            UpdateFlag(ExcludeFolders, UpdateFlagCommand::Reset);\n        });\n        toggleButton_includeFolders().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(ExcludeFolders, UpdateFlagCommand::Set);\n        });\n\n        // ToggleButton IncludeSubfolders\n        toggleButton_includeSubfolders().Checked([&](auto const&, auto const&) {\n            ValidateFlags(ExcludeSubfolders);\n            UpdateFlag(ExcludeSubfolders, UpdateFlagCommand::Reset);\n        });\n        toggleButton_includeSubfolders().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(ExcludeSubfolders, UpdateFlagCommand::Set);\n        });\n\n        // CheckBox EnumerateItems\n        toggleButton_enumItems().Checked([&](auto const&, auto const&) {\n            ValidateFlags(EnumerateItems);\n            UpdateFlag(EnumerateItems, UpdateFlagCommand::Set);\n        });\n        toggleButton_enumItems().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(EnumerateItems, UpdateFlagCommand::Reset);\n        });\n\n        // CheckBox RandomizeItems\n        toggleButton_randItems().Checked([&](auto const&, auto const&) {\n            ValidateFlags(RandomizeItems);\n            UpdateFlag(RandomizeItems, UpdateFlagCommand::Set);\n        });\n        toggleButton_randItems().Unchecked([&](auto const&, auto const&) {\n            UpdateFlag(RandomizeItems, UpdateFlagCommand::Reset);\n        });\n\n        // ButtonSettings\n        button_settings().Click([&](auto const&, auto const&) {\n            OpenSettingsApp();\n        });\n    }\n\n    void MainWindow::ToggleItem(int32_t id, bool checked)\n    {\n        _TRACER_;\n        Logger::debug(L\"Toggling item with id = {}\", id);\n        CComPtr<IPowerRenameItem> spItem;\n\n        if (SUCCEEDED(m_prManager->GetItemById(id, &spItem)))\n        {\n            spItem->PutSelected(checked);\n        }\n        UpdateCounts();\n    }\n\n    void MainWindow::ToggleAll()\n    {\n        _TRACER_;\n\n        UINT itemCount = 0;\n        m_prManager->GetItemCount(&itemCount);\n        bool selected = checkBox_selectAll().IsChecked().GetBoolean();\n        for (UINT i = 0; i < itemCount; i++)\n        {\n            CComPtr<IPowerRenameItem> spItem;\n            if (SUCCEEDED(m_prManager->GetItemByIndex(i, &spItem)))\n            {\n                spItem->PutSelected(selected);\n            }\n        }\n        UpdateCounts();\n    }\n\n    void MainWindow::SwitchView()\n    {\n        _TRACER_;\n\n        m_prManager->SwitchFilter(0);\n        UpdateCounts();\n    }\n\n    void MainWindow::Rename(bool closeWindow)\n    {\n        _TRACER_;\n\n        if (m_prManager)\n        {\n            m_prManager->Rename(m_window, closeWindow);\n        }\n\n        // Persist the current settings.  We only do this when\n        // a rename is actually performed.  Not when the user\n        // closes/cancels the dialog.\n        WriteSettings();\n    }\n\n    HRESULT MainWindow::ReadSettings()\n    {\n        _TRACER_;\n\n        bool persistState{ CSettingsInstance().GetPersistState() };\n        Logger::debug(L\"ReadSettings with persistState = {}\", persistState);\n\n        // Check if we should read flags from settings\n        // or the defaults from the manager.\n        DWORD flags = 0;\n        if (persistState)\n        {\n            flags = CSettingsInstance().GetFlags();\n\n            textBox_search().Text(LastRunSettingsInstance().GetSearchText().c_str());\n            textBox_replace().Text(LastRunSettingsInstance().GetReplaceText().c_str());\n        }\n        else\n        {\n            m_prManager->GetFlags(&flags);\n        }\n\n        m_prManager->PutFlags(flags);\n        SetCheckboxesFromFlags(flags);\n\n        return S_OK;\n    }\n\n    HRESULT MainWindow::WriteSettings()\n    {\n        _TRACER_;\n\n        // Check if we should store our settings\n        if (CSettingsInstance().GetPersistState())\n        {\n            DWORD flags = 0;\n            m_prManager->GetFlags(&flags);\n            CSettingsInstance().SetFlags(flags);\n\n            winrt::hstring searchTerm = textBox_search().Text();\n            LastRunSettingsInstance().SetSearchText(std::wstring{ searchTerm });\n\n            if (CSettingsInstance().GetMRUEnabled() && m_searchMRU)\n            {\n                CComPtr<IPowerRenameMRU> spSearchMRU;\n                if (SUCCEEDED(m_searchMRU->QueryInterface(IID_PPV_ARGS(&spSearchMRU))))\n                {\n                    spSearchMRU->AddMRUString(searchTerm.c_str());\n                }\n            }\n\n            winrt::hstring replaceTerm = textBox_replace().Text();\n            LastRunSettingsInstance().SetReplaceText(std::wstring{ replaceTerm });\n\n            if (CSettingsInstance().GetMRUEnabled() && m_replaceMRU)\n            {\n                CComPtr<IPowerRenameMRU> spReplaceMRU;\n                if (SUCCEEDED(m_replaceMRU->QueryInterface(IID_PPV_ARGS(&spReplaceMRU))))\n                {\n                    spReplaceMRU->AddMRUString(replaceTerm.c_str());\n                }\n            }\n\n            Trace::SettingsChanged();\n        }\n\n        return S_OK;\n    }\n\n    HRESULT MainWindow::OpenSettingsApp()\n    {\n        std::wstring path = get_module_folderpath(g_hostHInst);\n        path += L\"\\\\..\\\\PowerToys.exe\";\n\n        std::wstring openSettings = L\"--open-settings=PowerRename\";\n\n        CString commandLine;\n        commandLine.Format(_T(\"\\\"%s\\\"\"), path.c_str());\n        commandLine.AppendFormat(_T(\" %s\"), openSettings.c_str());\n\n        int nSize = commandLine.GetLength() + 1;\n        LPTSTR lpszCommandLine = new TCHAR[nSize];\n        _tcscpy_s(lpszCommandLine, nSize, commandLine);\n\n        STARTUPINFO startupInfo;\n        ZeroMemory(&startupInfo, sizeof(STARTUPINFO));\n        startupInfo.cb = sizeof(STARTUPINFO);\n        startupInfo.wShowWindow = SW_SHOWNORMAL;\n\n        PROCESS_INFORMATION processInformation;\n\n        // Start the resizer\n        CreateProcess(\n            NULL,\n            lpszCommandLine,\n            NULL,\n            NULL,\n            TRUE,\n            0,\n            NULL,\n            NULL,\n            &startupInfo,\n            &processInformation);\n\n        delete[] lpszCommandLine;\n\n        if (!CloseHandle(processInformation.hProcess))\n        {\n            return HRESULT_FROM_WIN32(GetLastError());\n        }\n        if (!CloseHandle(processInformation.hThread))\n        {\n            return HRESULT_FROM_WIN32(GetLastError());\n        }\n        return S_OK;\n    }\n\n    void MainWindow::SetCheckboxesFromFlags(DWORD flags)\n    {\n        if (flags & CaseSensitive)\n        {\n            checkBox_case().IsChecked(true);\n        }\n        if (flags & MatchAllOccurrences)\n        {\n            checkBox_matchAll().IsChecked(true);\n        }\n        if (flags & UseRegularExpressions)\n        {\n            checkBox_regex().IsChecked(true);\n        }\n        if (flags & EnumerateItems)\n        {\n            toggleButton_enumItems().IsChecked(true);\n        }\n        if (flags & RandomizeItems)\n        {\n            toggleButton_randItems().IsChecked(true);\n        }\n        if (flags & ExcludeFiles)\n        {\n            toggleButton_includeFiles().IsChecked(false);\n        }\n        if (flags & ExcludeFolders)\n        {\n            toggleButton_includeFolders().IsChecked(false);\n        }\n        if (flags & ExcludeSubfolders)\n        {\n            toggleButton_includeSubfolders().IsChecked(false);\n        }\n        if (flags & NameOnly)\n        {\n            comboBox_renameParts().SelectedIndex(1);\n        }\n        else if (flags & ExtensionOnly)\n        {\n            comboBox_renameParts().SelectedIndex(2);\n        }\n        if (flags & Uppercase)\n        {\n            toggleButton_upperCase().IsChecked(true);\n        }\n        else if (flags & Lowercase)\n        {\n            toggleButton_lowerCase().IsChecked(true);\n        }\n        else if (flags & Titlecase)\n        {\n            toggleButton_titleCase().IsChecked(true);\n        }\n        else if (flags & Capitalized)\n        {\n            toggleButton_capitalize().IsChecked(true);\n        }\n    }\n\n    void MainWindow::UpdateCounts()\n    {\n        // This method is CPU intensive.  We disable it during certain operations\n        // for performance reasons.\n        if (m_disableCountUpdate)\n        {\n            return;\n        }\n\n        UINT selectedCount = 0;\n        UINT renamingCount = 0;\n        if (m_prManager)\n        {\n            m_prManager->GetSelectedItemCount(&selectedCount);\n            m_prManager->GetRenameItemCount(&renamingCount);\n        }\n\n        if (m_selectedCount != selectedCount ||\n            m_renamingCount != renamingCount)\n        {\n            m_selectedCount = selectedCount;\n            m_renamingCount = renamingCount;\n\n            // Update Rename button state\n            button_rename().IsEnabled(renamingCount > 0);\n        }\n\n        RenamedCount(hstring{ std::to_wstring(m_renamingCount) });\n    }\n\n    HRESULT MainWindow::OnRename(_In_ IPowerRenameItem* /*renameItem*/)\n    {\n        UpdateCounts();\n        return S_OK;\n    }\n\n    HRESULT MainWindow::OnRegExCompleted(_In_ DWORD)\n    {\n        _TRACER_;\n\n        if (m_flagValidationInProgress)\n        {\n            m_flagValidationInProgress = false;\n        }\n\n        UpdateCounts();\n        InvalidateItemListViewState();\n        return S_OK;\n    }\n\n    HRESULT MainWindow::OnRenameCompleted(bool closeUIWindowAfterRenaming)\n    {\n        _TRACER_;\n\n        Logger::debug(L\"Renaming completed. Close UI window - {}\", closeUIWindowAfterRenaming);\n        if (closeUIWindowAfterRenaming)\n        {\n            // Close the window\n            PostMessage(m_window, WM_CLOSE, static_cast<WPARAM>(0), static_cast<LPARAM>(0));\n        }\n        else\n        {\n            // Force renaming work to start so newly renamed items are processed right away\n            SearchReplaceChanged(true);\n        }\n\n        InvalidateItemListViewState();\n\n        return S_OK;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/powerrename/PowerRenameUILib/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"SearchBox.PlaceholderText\" xml:space=\"preserve\">\n    <value>搜索</value>\n  </data>\n  <data name=\"RegExCheatSheet_Title.Text\" xml:space=\"preserve\">\n    <value>正则表达式用法</value>\n  </data>\n  <data name=\"RegExCheatSheet_MatchAny\" xml:space=\"preserve\">\n    <value>一个任意字符</value>\n  </data>\n  <data name=\"RegExCheatSheet_MatchDigit\" xml:space=\"preserve\">\n    <value>一个数字，[0-9]</value>\n  </data>\n  <data name=\"RegExCheatSheet_MatchNonDigit\" xml:space=\"preserve\">\n    <value>一个非数字，[^0-9]</value>\n  </data>\n  <data name=\"RegExCheatSheet_MatchNonWS\" xml:space=\"preserve\">\n    <value>一个非空白字符，[^\\\\s]</value>\n  </data>\n  <data name=\"RegExCheatSheet_MatchWordChar\" xml:space=\"preserve\">\n    <value>一个英文字符，[a-zA-Z_0-9]</value>\n  </data>\n  <data name=\"RegExCheatSheet_MatchOneOrMoreWS\" xml:space=\"preserve\">\n    <value>一个及以上非空白字符</value>\n  </data>\n  <data name=\"RegExCheatSheet_MatchWordBoundary\" xml:space=\"preserve\">\n    <value>一个英文单词的边界，[a-zA-Z0-9_]</value>\n  </data>\n  <data name=\"RegExCheatSheet_LearnMore.Text\" xml:space=\"preserve\">\n    <value>了解正则表达式</value>\n  </data>\n  <data name=\"ReplaceBox.PlaceholderText\" xml:space=\"preserve\">\n    <value>替换为</value>\n  </data>\n  <data name=\"CounterCheatSheet_Title.Text\" xml:space=\"preserve\">\n    <value>数字编号器用法</value>\n  </data>\n  <data name=\"CounterCheatSheet_Simple\" xml:space=\"preserve\">\n    <value>普通的递增计数器</value>\n  </data>\n  <data name=\"CounterCheatSheet_Start\" xml:space=\"preserve\">\n    <value>自定义起始值</value>\n  </data>\n  <data name=\"CounterCheatSheet_Increment\" xml:space=\"preserve\">\n    <value>自定义增量</value>\n  </data>\n  <data name=\"CounterCheatSheet_Padding\" xml:space=\"preserve\">\n    <value>自定义前导零</value>\n  </data>\n  <data name=\"CounterCheatSheet_Complex\" xml:space=\"preserve\">\n    <value>更复杂的自定义</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_Title.Text\" xml:space=\"preserve\">\n    <value>文件名参数</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_FullYear\" xml:space=\"preserve\">\n    <value>年份，2023</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_YearLastTwoDigits\" xml:space=\"preserve\">\n    <value>年份后两位，23</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_YearLastDigit\" xml:space=\"preserve\">\n    <value>年份后一位，3</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MonthName\" xml:space=\"preserve\">\n    <value>月份名，一月</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MonthNameAbbr\" xml:space=\"preserve\">\n    <value>月份缩写，1月</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MonthDigitLZero\" xml:space=\"preserve\">\n    <value>月份补零，01-12</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MonthDigit\" xml:space=\"preserve\">\n    <value>月份，1-12</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_DayName\" xml:space=\"preserve\">\n    <value>星期名，星期一</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_DayNameAbbr\" xml:space=\"preserve\">\n    <value>星期缩写，周一</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_DayDigitLZero\" xml:space=\"preserve\">\n    <value>日期补零，01-31</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_DayDigit\" xml:space=\"preserve\">\n    <value>日期，1-31</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_HoursLZero\" xml:space=\"preserve\">\n    <value>小时补零，00-23</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_Hours\" xml:space=\"preserve\">\n    <value>小时，0-23</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MinutesLZero\" xml:space=\"preserve\">\n    <value>分钟补零，00-59</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_Minutes\" xml:space=\"preserve\">\n    <value>分钟，0-59</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_SecondsLZero\" xml:space=\"preserve\">\n    <value>秒钟补零，00-59</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_Seconds\" xml:space=\"preserve\">\n    <value>秒钟，0-59</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MilliSeconds3D\" xml:space=\"preserve\">\n    <value>毫秒，123</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MilliSeconds2D\" xml:space=\"preserve\">\n    <value>毫秒前两位，12</value>\n  </data>\n  <data name=\"DateTimeCheatSheet_MilliSeconds1D\" xml:space=\"preserve\">\n    <value>毫秒前一位，1</value>\n  </data>\n  <data name=\"CheckBox_RegEx.Content\" xml:space=\"preserve\">\n    <value>正则表达式</value>\n  </data>\n  <data name=\"CheckBox_MatchAll.Content\" xml:space=\"preserve\">\n    <value>全部替换</value>\n  </data>\n  <data name=\"CheckBox_Case.Content\" xml:space=\"preserve\">\n    <value>区分大小写</value>\n  </data>\n  <data name=\"TextBox_ApplyTo.Text\" xml:space=\"preserve\">\n    <value>目标</value>\n  </data>\n  <data name=\"DocsButton.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>帮助</value>\n  </data>\n  <data name=\"DocsButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>帮助</value>\n  </data>\n  <data name=\"ToggleButton_IncludeFiles.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>文件</value>\n  </data>\n  <data name=\"ToggleButton_IncludeFiles.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>文件</value>\n  </data>\n  <data name=\"ToggleButton_IncludeFolders.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>文件夹</value>\n  </data>\n  <data name=\"ToggleButton_IncludeFolders.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>文件夹</value>\n  </data>\n  <data name=\"ToggleButton_IncludeSubFolders.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>文件夹内</value>\n  </data>\n  <data name=\"ToggleButton_IncludeSubFolders.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>文件夹内</value>\n  </data>\n  <data name=\"TextBlock_TextFormatting.Text\" xml:space=\"preserve\">\n    <value>文本格式</value>\n  </data>\n  <data name=\"ToggleButton_Lowercase.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>转小写</value>\n  </data>\n  <data name=\"ToggleButton_Lowercase.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>转小写</value>\n  </data>\n  <data name=\"ToggleButton_Uppercase.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>转大写</value>\n  </data>\n  <data name=\"ToggleButton_Uppercase.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>转大写</value>\n  </data>\n  <data name=\"ToggleButton_Titlecase.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>转标题</value>\n  </data>\n  <data name=\"ToggleButton_Titlecase.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>转标题</value>\n  </data>\n  <data name=\"ToggleButton_Capitalize.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>转首字母大写</value>\n  </data>\n  <data name=\"ToggleButton_Capitalize.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>转首字母大写</value>\n  </data>\n  <data name=\"ToggleButton_EnumItems.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>添加数字编号</value>\n  </data>\n  <data name=\"ToggleButton_EnumItems.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>添加数字编号</value>\n  </data>\n  <data name=\"SelectAllCheckBox.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>全选或取消全选</value>\n  </data>\n  <data name=\"FilterButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>筛选</value>\n  </data>\n  <data name=\"FilterButton.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>筛选</value>\n  </data>\n  <data name=\"ShowAll.Text\" xml:space=\"preserve\">\n    <value>所有文件</value>\n  </data>\n  <data name=\"ShowOnly.Text\" xml:space=\"preserve\">\n    <value>符合搜索的文件</value>\n  </data>\n  <data name=\"TxtBlock_Original.Text\" xml:space=\"preserve\">\n    <value>原文件</value>\n  </data>\n  <data name=\"TxtBlock_Renamed.Text\" xml:space=\"preserve\">\n    <value>命名为</value>\n  </data>\n  <data name=\"TxtBlock_ButtonSettings.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"TxtBlock_ButtonSettings.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"TxtBlock_ButtonApply.Text\" xml:space=\"preserve\">\n    <value>执行</value>\n  </data>\n  <data name=\"ButtonApply.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>应用</value>\n  </data>\n  <data name=\"TxtBlock_ButtonApplyAndClose.Text\" xml:space=\"preserve\">\n    <value>执行并关闭</value>\n  </data>\n  <data name=\"RegExButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>正则用法提示</value>\n  </data>\n  <data name=\"RegExButton.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>正则用法提示</value>\n  </data>\n  <data name=\"FileCreationButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>参数用法提示</value>\n  </data>\n  <data name=\"FileCreationButton.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>参数用法提示</value>\n  </data>\n  <data name=\"ErrorMessage_FileNameTooLong\" xml:space=\"preserve\">\n    <value>文件名过长</value>\n  </data>\n  <data name=\"ErrorMessage_InvalidChar\" xml:space=\"preserve\">\n    <value>文件名不能包含以下字符：&#xD;&#xA; &gt; &lt; | \" : ? * \\ /</value>\n  </data>\n  <data name=\"RenameParts_FilenameAndExtension.Content\" xml:space=\"preserve\">\n    <value>文件名 + 扩展名</value>\n  </data>\n  <data name=\"RenameParts_FilenameOnly.Content\" xml:space=\"preserve\">\n    <value>仅文件名</value>\n  </data>\n  <data name=\"RenameParts_ExtensionOnly.Content\" xml:space=\"preserve\">\n    <value>仅扩展名</value>\n  </data>\n  <data name=\"RandomizerCheatSheet_Alnum\" xml:space=\"preserve\">\n    <value>所设长度的随机数字和大小写字母，0-9 A-z</value>\n  </data>\n  <data name=\"RandomizerCheatSheet_Alpha\" xml:space=\"preserve\">\n    <value>所设长度的随机大小写字母，A-z</value>\n  </data>\n  <data name=\"RandomizerCheatSheet_Digit\" xml:space=\"preserve\">\n    <value>所设长度的随机数字，0-9</value>\n  </data>\n  <data name=\"RandomizerCheatSheet_Title.Text\" xml:space=\"preserve\">\n    <value>随机字符生成器用法</value>\n  </data>\n  <data name=\"RandomizerCheatSheet_Uuid\" xml:space=\"preserve\">\n    <value>随机 UUID v4</value>\n  </data>\n  <data name=\"ToggleButton_RandItems.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>添加随机字符</value>\n  </data>\n  <data name=\"ToggleButton_RandItems.[using:Microsoft.UI.Xaml.Controls]ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>添加随机字符</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/powerrename/dll/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"PowerRename\" xml:space=\"preserve\">\n    <value>批量重命名(&amp;W)</value>\n    <comment>do not loc, product name</comment>\n  </data>\n  <data name=\"PowerRename_App_Name\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>do not loc, product name</comment>\n  </data>\n  <data name=\"PowerRename_Context_Menu_Entry\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>PowerRename is a product name. do not loc it. The &amp; allows to use W as a keyboard accelerator.</comment>\n  </data>\n  <data name=\"Settings_Description\" xml:space=\"preserve\">\n    <value>A Windows Shell extension for more advanced bulk renaming using search and replace or regular expressions.</value>\n  </data>\n  <data name=\"Restore_Search\" xml:space=\"preserve\">\n    <value>Restore search, replace and flags values on launch from previous run.</value>\n  </data>\n  <data name=\"Enable_Auto\" xml:space=\"preserve\">\n    <value>Enable autocomplete and autosuggest of recently used inputs for search and replace values.</value>\n  </data>\n  <data name=\"Max_Items\" xml:space=\"preserve\">\n    <value>Maximum number of items to show in recently used list for autocomplete dropdown.</value>\n  </data>\n  <data name=\"Icon_Context_Menu\" xml:space=\"preserve\">\n    <value>Show icon on context menu.</value>\n    <comment>The icon for PowerRename to be inside with Windows File Explorer right click context menu</comment>\n  </data>\n  <data name=\"Extended_Menu_Info\" xml:space=\"preserve\">\n    <value>Only show the PowerRename menu item on the extended context menu (Shift + Right-click).</value>\n  </data>\n  <data name=\"Use_Boost_Lib\" xml:space=\"preserve\">\n    <value>Use Boost library (provides extended features but may use different regex syntax).</value>\n    <comment>Boost is a product name, should not be translated</comment>\n  </data>\n</root>\n"
  },
  {
    "path": "PowerToys/src/modules/previewpane/GcodePreviewHandler/Properties/Resource.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"GcodeNotPreviewedError\" xml:space=\"preserve\">\n    <value>由于 PowerToys G-code 预览器出现错误，无法预览此文件。</value>\n    <comment>This text is displayed if G-code fails to preview</comment>\n  </data>\n  <data name=\"GcodeWithoutEmbeddedThumbnails\" xml:space=\"preserve\">\n    <value>此 G-code 文件没有内置缩略图。</value>\n  </data>\n  <data name=\"GpoDisabledErrorText\" xml:space=\"preserve\">\n    <value>组策略已禁止该功能。请联系你的电脑管理员。</value>\n    <comment>GPO stands for the Windows Group Policy Object feature.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/previewpane/MarkdownPreviewHandler/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"BlockedImageInfoText\" xml:space=\"preserve\">\n    <value>一些图片已被屏蔽，防止电脑访问未知网址引起危险。启用此选项允许查看图片。</value>\n    <comment>This text is displayed if image is blocked from being displayed.</comment>\n  </data>\n  <data name=\"MarkdownNotPreviewedError\" xml:space=\"preserve\">\n    <value>由于 PowerToys Markdown 预览器出现错误，无法预览此文件。</value>\n    <comment>This text is displayed if markdown fails to preview</comment>\n  </data>\n  <data name=\"GpoDisabledErrorText\" xml:space=\"preserve\">\n    <value>组策略已禁止该功能。请联系你的电脑管理员。</value>\n    <comment>GPO stands for the Windows Group Policy Object feature.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/previewpane/MonacoPreviewHandler/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Max_File_Size_Error\" xml:space=\"preserve\">\n      <value>文件过大，无法预览。\n最大文件大小：%1KB</value>\n    <comment>Error message which is shown when the file is too big. %1 gets replaced by a value. Leave KB (means Kilobyte)</comment>\n  </data>\n  <data name=\"Exception_Occurred\" xml:space=\"preserve\">\n      <value>文件预览发生错误：\n      </value>\n    <comment>Will be shown when an exception occurred.</comment>\n  </data>\n  <data name=\"Loading_Screen_Message\" xml:space=\"preserve\">\n      <value>加载中...</value>\n  </data>\n  <data name=\"WebView2_Not_Installed_Message\" xml:space=\"preserve\">\n      <value>未安装 WebView2。</value>\n  </data>\n  <data name=\"Download_WebView2\" xml:space=\"preserve\">\n      <value>下载 WebView2 即可预览该文件。</value>\n  </data>\n  <data name=\"GpoDisabledErrorText\" xml:space=\"preserve\">\n    <value>组策略已禁止该功能。请联系你的电脑管理员。</value>\n    <comment>GPO stands for the Windows Group Policy Object feature.</comment>\n  </data>\n  <data name=\"Access_Denied_Exception_Message\" xml:space=\"preserve\">\n    <value>拒绝访问: 您当前无权打开该文件。请联系文件所有者或电脑管理员以获得许可。</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/previewpane/PdfPreviewHandler/Properties/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"PdfMorePagesMessage\" xml:space=\"preserve\">\n    <value>此 PDF 文档超过 10 页，剩余部分请打开浏览。</value>\n    <comment>This text is displayed if PDF has more than 10 pages.</comment>\n  </data>\n  <data name=\"PdfNotPreviewedError\" xml:space=\"preserve\">\n    <value>由于 PowerToys PDF 预览器出现错误，无法预览此文件。</value>\n    <comment>This text is displayed if PDF fails to preview</comment>\n  </data>\n  <data name=\"PdfPasswordProtectedError\" xml:space=\"preserve\">\n    <value>PDF 文档已加密。</value>\n    <comment>This text is displayed if PDF is password protected.</comment>\n  </data>\n  <data name=\"GpoDisabledErrorText\" xml:space=\"preserve\">\n    <value>组策略已禁止该功能。请联系你的电脑管理员。</value>\n    <comment>GPO stands for the Windows Group Policy Object feature.</comment>\n  </data>\n</root>\n"
  },
  {
    "path": "PowerToys/src/modules/previewpane/QoiPreviewHandler/Properties/Resource.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"QoiNotPreviewedError\" xml:space=\"preserve\">\n    <value>由于 PowerToys QOI 预览器出现错误，无法预览此文件。</value>\n    <comment>This text is displayed if Qoi fails to preview</comment>\n  </data>\n  <data name=\"GpoDisabledErrorText\" xml:space=\"preserve\">\n    <value>组策略已禁止该功能。请联系你的电脑管理员。</value>\n    <comment>GPO stands for the Windows Group Policy Object feature.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/previewpane/SvgPreviewHandler/Properties/Resource.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"BlockedElementInfoText\" xml:space=\"preserve\">\n    <value>一些元素已被屏蔽，防止电脑访问未知网址引起危险。启用此选项允许查看所有元素。</value>\n  </data>\n  <data name=\"SvgNotPreviewedError\" xml:space=\"preserve\">\n    <value>由于 PowerToys SVG 预览器出现错误，无法预览此文件。</value>\n  </data>\n  <data name=\"GpoDisabledErrorText\" xml:space=\"preserve\">\n    <value>组策略已禁止该功能。请联系你的电脑管理员。</value>\n    <comment>GPO stands for the Windows Group Policy Object feature.</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/previewpane/powerpreview/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"General_Description\" xml:space=\"preserve\">\n    <value>PowerToys add-ons for Windows File Explorer.</value>\n  </data>\n  <data name=\"Module_Name\" xml:space=\"preserve\">\n    <value>File Explorer</value>\n  </data>\n  <data name=\"Icon_Key_Name\" xml:space=\"preserve\">\n    <value>pt-power-preview</value>\n  </data>\n  <data name=\"Explr_Icons_Prev_Sttngs_Group_Desc\" xml:space=\"preserve\">\n    <value>Settings Group Header Text</value>\n  </data>\n  <data name=\"Explr_Icons_Prev_Sttngs_Group_Text\" xml:space=\"preserve\">\n    <value>Explorer Icons</value>\n  </data>\n  <data name=\"Prvpane_File_Prev_Sttngs_Group_Desc\" xml:space=\"preserve\">\n    <value>Settings Group Header Text</value>\n  </data>\n  <data name=\"Prvpane_File_Prev_Sttngs_Group_Text\" xml:space=\"preserve\">\n    <value>Preview pane extensions</value>\n  </data>\n  <data name=\"Prevpane_Md_Settings_Description\" xml:space=\"preserve\">\n    <value>Markdown Previewer</value>\n  </data>\n  <data name=\"Prevpane_Monaco_Settings_Description\" xml:space=\"preserve\">\n    <value>Developer files Previewer</value>\n  </data>  \n  <data name=\"Prevpane_Md_Settings_Displayname\" xml:space=\"preserve\">\n    <value>Markdown Previewer</value>\n  </data>\n  <data name=\"Prevpane_Svg_Settings_Description\" xml:space=\"preserve\">\n    <value>Svg Previewer</value>\n  </data>\n  <data name=\"Prevpane_Svg_Settings_Displayname\" xml:space=\"preserve\">\n    <value>SVG Previewer</value>\n  </data>\n  <data name=\"Svg_Thumbnail_Provider_Settings_Description\" xml:space=\"preserve\">\n    <value>Svg Thumbnail Provider</value>\n  </data>\n  <data name=\"Explr_Svg_Settings_Description\" xml:space=\"preserve\">\n    <value>Render SVG images</value>\n  </data>\n  <data name=\"FileExplorer_Admin_Restart_Warning_Description\" xml:space=\"preserve\">\n    <value>一些预览组件的更改不支持立即生效，请以管理员身份重启软件以生效。</value>\n  </data>\n  <data name=\"FileExplorer_Admin_Restart_Warning_Title\" xml:space=\"preserve\">\n    <value>预览增强组件更改</value>\n  </data>\n  <data name=\"FileExplorer_Admin_Restart_Warning_Open_Settings\" xml:space=\"preserve\">\n    <value>打开设置</value>\n  </data>\n  <data name=\"FileExplorer_Admin_Restart_Warning_Dont_Show_Again\" xml:space=\"preserve\">\n    <value>不再显示</value>\n  </data>\n  <data name=\"Prevpane_Pdf_Settings_Description\" xml:space=\"preserve\">\n    <value>PDF Previewer</value>\n  </data>\n  <data name=\"Prevpane_Pdf_Settings_Displayname\" xml:space=\"preserve\">\n    <value>PDF Previewer</value>\n  </data>\n  <data name=\"Pdf_Thumbnail_Provider_Settings_Description\" xml:space=\"preserve\">\n    <value>Pdf Thumbnail Provider</value>\n  </data>\n  <data name=\"Gcode_Thumbnail_Provider_Settings_Description\" xml:space=\"preserve\">\n    <value>G-code Thumbnail Provider</value>\n  </data>\n  <data name=\"Prevpane_Gcode_Settings_Description\" xml:space=\"preserve\">\n    <value>G-code Previewer</value>\n  </data>\n  <data name=\"Prevpane_Gcode_Settings_Displayname\" xml:space=\"preserve\">\n    <value>G-code Previewer</value>\n  </data>\n  <data name=\"Stl_Thumbnail_Provider_Settings_Description\" xml:space=\"preserve\">\n    <value>Stl Thumbnail Provider</value>\n  </data>\n  <data name=\"Prevpane_Qoi_Settings_Description\" xml:space=\"preserve\">\n    <value>Qoi Previewer</value>\n  </data>\n  <data name=\"Qoi_Thumbnail_Provider_Settings_Description\" xml:space=\"preserve\">\n    <value>Qoi Thumbnail Provider</value>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/modules/registrypreview/RegistryPreview/RegistryPreviewXAML/MainWindow.xaml.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\n\nusing ManagedCommon;\nusing Microsoft.UI;\nusing Microsoft.UI.Xaml;\nusing Microsoft.UI.Xaml.Controls;\nusing Microsoft.UI.Xaml.Media;\nusing RegistryPreviewUILib;\nusing Windows.Data.Json;\nusing Windows.Graphics;\nusing WinUIEx;\n\nnamespace RegistryPreview\n{\n    public sealed partial class MainWindow : WindowEx\n    {\n        // Const values\n        private const string APPNAME = \"注册表预览\";\n\n        // private members\n        private Microsoft.UI.Windowing.AppWindow appWindow;\n        private JsonObject jsonWindowPlacement;\n        private string settingsFolder = string.Empty;\n        private string windowPlacementFile = \"app-placement.json\";\n\n        private RegistryPreviewMainPage MainPage { get; }\n\n        internal MainWindow()\n        {\n            this.InitializeComponent();\n\n            // Open settings file; this moved to after the window tweak because it gives the window time to start up\n            settingsFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + @\"\\Microsoft\\PowerToys\\\" + APPNAME;\n            OpenWindowPlacementFile(settingsFolder, windowPlacementFile);\n\n            // Update the Win32 looking window with the correct icon (and grab the appWindow handle for later)\n            IntPtr windowHandle = this.GetWindowHandle();\n            WindowId windowId = Win32Interop.GetWindowIdFromWindow(windowHandle);\n            appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(windowId);\n            appWindow.SetIcon(\"Assets\\\\RegistryPreview\\\\RegistryPreview.ico\");\n\n            // TODO(stefan)\n            appWindow.Closing += AppWindow_Closing;\n            Activated += MainWindow_Activated;\n\n            // Extend the canvas to include the title bar so the app can support theming\n            ExtendsContentIntoTitleBar = true;\n            WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(windowHandle);\n            SetTitleBar(titleBar);\n\n            // if have settings, update the location of the window\n            if (jsonWindowPlacement != null)\n            {\n                // resize the window\n                if (jsonWindowPlacement.ContainsKey(\"appWindow.Size.Width\") && jsonWindowPlacement.ContainsKey(\"appWindow.Size.Height\"))\n                {\n                    SizeInt32 size;\n                    size.Width = (int)jsonWindowPlacement.GetNamedNumber(\"appWindow.Size.Width\");\n                    size.Height = (int)jsonWindowPlacement.GetNamedNumber(\"appWindow.Size.Height\");\n\n                    // check to make sure the size values are reasonable before attempting to restore the last saved size\n                    if (size.Width >= 320 && size.Height >= 240)\n                    {\n                        appWindow.Resize(size);\n                    }\n                }\n\n                // reposition the window\n                if (jsonWindowPlacement.ContainsKey(\"appWindow.Position.X\") && jsonWindowPlacement.ContainsKey(\"appWindow.Position.Y\"))\n                {\n                    PointInt32 point;\n                    point.X = (int)jsonWindowPlacement.GetNamedNumber(\"appWindow.Position.X\");\n                    point.Y = (int)jsonWindowPlacement.GetNamedNumber(\"appWindow.Position.Y\");\n\n                    // check to make sure the move values are reasonable before attempting to restore the last saved location\n                    if (point.X >= 0 && point.Y >= 0)\n                    {\n                        appWindow.Move(point);\n                    }\n                }\n            }\n\n            MainPage = new RegistryPreviewMainPage(this, this.UpdateWindowTitle, App.AppFilename);\n\n            WindowHelpers.BringToForeground(windowHandle);\n        }\n\n        private void MainWindow_Activated(object sender, WindowActivatedEventArgs args)\n        {\n            if (args.WindowActivationState == WindowActivationState.Deactivated)\n            {\n                titleBarText.Foreground =\n                    (SolidColorBrush)Application.Current.Resources[\"WindowCaptionForegroundDisabled\"];\n            }\n            else\n            {\n                titleBarText.Foreground =\n                    (SolidColorBrush)Application.Current.Resources[\"WindowCaptionForeground\"];\n            }\n        }\n\n        private void Grid_Loaded(object sender, RoutedEventArgs e)\n        {\n            MainGrid.Children.Add(MainPage);\n            Grid.SetRow(MainPage, 1);\n        }\n\n        public void UpdateWindowTitle(string title)\n        {\n            string filename = title;\n\n            if (string.IsNullOrEmpty(filename))\n            {\n                titleBarText.Text = APPNAME;\n                appWindow.Title = APPNAME;\n            }\n            else\n            {\n                string[] file = filename.Split('\\\\');\n                if (file.Length > 0)\n                {\n                    titleBarText.Text = file[file.Length - 1] + \" - \" + APPNAME;\n                }\n                else\n                {\n                    titleBarText.Text = filename + \" - \" + APPNAME;\n                }\n\n                // Continue to update the window's title, after updating the custom title bar\n                appWindow.Title = titleBarText.Text;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/modules/registrypreview/RegistryPreviewUILib/Strings/en-US/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"EditButton.Label\" xml:space=\"preserve\">\n    <value>编辑文本</value>\n  </data>\n  <data name=\"ErrorDialogTitle\" xml:space=\"preserve\">\n    <value>错误</value>\n  </data>\n  <data name=\"FileEditorError\" xml:space=\"preserve\">\n    <value>无法打开 .reg 注册表文件编辑器。</value>\n  </data>\n  <data name=\"FileNotFound\" xml:space=\"preserve\">\n    <value>文件不存在！</value>\n  </data>\n  <data name=\"FileSaveError\" xml:space=\"preserve\">\n    <value>文件无法写入。</value>\n  </data>\n  <data name=\"FilterAllFiles\" xml:space=\"preserve\">\n    <value>所有文件 (*.*)</value>\n  </data>\n  <data name=\"FilterRegistryName\" xml:space=\"preserve\">\n    <value>注册表文件 (*.reg)</value>\n  </data>\n  <data name=\"InvalidBinary\" xml:space=\"preserve\">\n    <value>(无效二进制值)</value>\n  </data>\n  <data name=\"InvalidDword\" xml:space=\"preserve\">\n    <value>(无效 DWORD (32 位) 值)</value>\n  </data>\n  <data name=\"InvalidQword\" xml:space=\"preserve\">\n    <value>(无效 QWORD (64 位) 值)</value>\n  </data>\n  <data name=\"InvalidRegistryFile\" xml:space=\"preserve\">\n    <value> 不是有效的注册表文件！</value>\n  </data>\n  <data name=\"InvalidRegistryFileTitle\" xml:space=\"preserve\">\n    <value>非注册表文件</value>\n  </data>\n  <data name=\"InvalidString\" xml:space=\"preserve\">\n    <value>(无效字符串值)</value>\n  </data>\n  <data name=\"LargeRegistryFile\" xml:space=\"preserve\">\n    <value> 大于 10MB，注册表预览工具无法打开该文件。</value>\n  </data>\n  <data name=\"LargeRegistryFileTitle\" xml:space=\"preserve\">\n    <value>文件过大！</value>\n  </data>\n  <data name=\"NameColumn.Header\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"NoNodesFoundInFile\" xml:space=\"preserve\">\n    <value>找不到有效的键</value>\n  </data>\n  <data name=\"OkButtonText\" xml:space=\"preserve\">\n    <value>好的</value>\n    <comment>as on the OK button</comment>\n  </data>\n  <data name=\"OpenButton.Label\" xml:space=\"preserve\">\n    <value>打开</value>\n  </data>\n  <data name=\"OpenDialogTitle\" xml:space=\"preserve\">\n    <value>打开注册表文件</value>\n  </data>\n  <data name=\"RefreshButton.Label\" xml:space=\"preserve\">\n    <value>重新加载文件</value>\n  </data>\n  <data name=\"RegistryButton.Label\" xml:space=\"preserve\">\n    <value>打开注册表编辑器</value>\n  </data>\n  <data name=\"RegistryJumpToKeyButton.Label\" xml:space=\"preserve\">\n    <value>打开键</value>\n  </data>\n  <data name=\"SaveDialogTitle\" xml:space=\"preserve\">\n    <value>另存为</value>\n  </data>\n  <data name=\"SaveAsButton.Label\" xml:space=\"preserve\">\n    <value>另存为</value>\n  </data>\n  <data name=\"SaveButton.Label\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"SuggestFileName\" xml:space=\"preserve\">\n    <value>新建注册表文件</value>\n  </data>\n  <data name=\"titleBarText.ApplicationTitle\" xml:space=\"preserve\">\n    <value>注册表预览</value>\n  </data>\n  <data name=\"ToolTipAddedKey\" xml:space=\"preserve\">\n    <value>如果不存在，键将被自动创建</value>\n  </data>\n  <data name=\"ToolTipBinaryValue\" xml:space=\"preserve\">\n    <value>二进制值将写入到注册表</value>\n  </data>\n  <data name=\"ToolTipDeletedKey\" xml:space=\"preserve\">\n    <value>键将被删除</value>\n  </data>\n  <data name=\"ToolTipDeletedValue\" xml:space=\"preserve\">\n    <value>值将被删除</value>\n  </data>\n  <data name=\"ToolTipErrorKey\" xml:space=\"preserve\">\n    <value>键无法解析</value>\n  </data>\n  <data name=\"ToolTipErrorValue\" xml:space=\"preserve\">\n    <value>值存在语法错误</value>\n  </data>\n  <data name=\"ToolTipStringValue\" xml:space=\"preserve\">\n    <value>字符串值将写入到注册表</value>\n  </data>\n  <data name=\"TypeColumn.Header\" xml:space=\"preserve\">\n    <value>类型</value>\n    <comment>noun, as in \"a type of...\"</comment>\n  </data>\n  <data name=\"UACDialogError\" xml:space=\"preserve\">\n    <value>打开和写入系统注册表需要管理员权限，在刚才的弹窗中请点击允许。</value>\n  </data>\n  <data name=\"UACDialogTitle\" xml:space=\"preserve\">\n    <value>获取管理员权限</value>\n  </data>\n  <data name=\"ValueColumn.Header\" xml:space=\"preserve\">\n    <value>数据</value>\n  </data>\n  <data name=\"WriteButton.Label\" xml:space=\"preserve\">\n    <value>写入到注册表</value>\n  </data>\n  <data name=\"YesNoCancelDialogCloseButtonText\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"YesNoCancelDialogContent\" xml:space=\"preserve\">\n    <value>文件有改动，现在保存吗？</value>\n  </data>\n  <data name=\"YesNoCancelDialogPrimaryButtonText\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"YesNoCancelDialogSecondaryButtonText\" xml:space=\"preserve\">\n    <value>不保存</value>\n  </data>\n  <data name=\"YesNoCancelDialogTitle\" xml:space=\"preserve\">\n    <value>注册表预览</value>\n  </data>\n  <data name=\"ZeroLength\" xml:space=\"preserve\">\n    <value>(零长度二进制值)</value>\n  </data>\n  <data name=\"ContextMenu_CopyKeyPath.Text\" xml:space=\"preserve\">\n    <value>复制路径</value>\n    <comment>Like \"Copy item\"</comment>\n  </data>\n  <data name=\"ContextMenu_CopyName.Text\" xml:space=\"preserve\">\n    <value>复制名称</value>\n    <comment>Like \"Copy item\"</comment>\n  </data>\n  <data name=\"ContextMenu_CopyType.Text\" xml:space=\"preserve\">\n    <value>复制类型</value>\n    <comment>Like \"Copy item\"</comment>\n  </data>\n  <data name=\"ContextMenu_CopyData.Text\" xml:space=\"preserve\">\n    <value>复制数据</value>\n    <comment>Like \"Copy item\"</comment>\n  </data>\n  <data name=\"ContextMenu_CopyValue.Text\" xml:space=\"preserve\">\n    <value>复制此注册表值</value>\n    <comment>Like \"Copy item\"</comment>\n  </data>\n  <data name=\"ContextMenu_CopyValueWithPath.Text\" xml:space=\"preserve\">\n    <value>复制此注册表值与路径</value>\n    <comment>Like \"Copy item\"</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/runner/Resources.resx",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"ERROR\" xml:space=\"preserve\">\n    <value>PowerToys 错误</value>\n  </data>\n  <data name=\"COULDNOT_RESTART_NONELEVATED\" xml:space=\"preserve\">\n    <value>无法以用户身份启动 PowerToys！</value>\n  </data>\n  <data name=\"COULDNOT_RESTART_ELEVATED\" xml:space=\"preserve\">\n    <value>无法以管理员身份启动 PowerToys！</value>\n  </data>\n  <data name=\"ANOTHER_INSTANCE_RUNNING\" xml:space=\"preserve\">\n    <value>PowerToys 已经在运行。</value>\n  </data>\n  <data name=\"AUTOUPDATE_SUCCESS\" xml:space=\"preserve\">\n    <value>PowerToys 已成功更新！</value>\n  </data>\n  <data name=\"MSI_VERSION_IS_ALREADY_RUNNING\" xml:space=\"preserve\">\n    <value>旧版 MSI 安装包的 PowerToys 正在运行。</value>\n  </data>\n  <data name=\"DOWNLOAD_UPDATE_ERROR\" xml:space=\"preserve\">\n    <value>无法下载 PowerToys 更新！请在 GitHub 上报告该问题。</value>\n  </data>\n  <data name=\"OLDER_MSIX_UNINSTALLED\" xml:space=\"preserve\">\n    <value>已经卸载了旧版 MSIX 安装包的 PowerToys。</value>\n  </data>\n  <data name=\"PT_UPDATE_MESSAGE_BOX_TEXT\" xml:space=\"preserve\">\n    <value>PowerToys 已成功更新！</value>\n  </data>\n  <data name=\"STARTUP_DISABLED_BY_POLICY\" xml:space=\"preserve\">\n    <value>此功能已被管理员通过组策略禁止。</value>\n  </data>\n  <data name=\"STARTUP_DISABLED_BY_USER\" xml:space=\"preserve\">\n    <value>此功能已在 &lt;a href=&quot;https://ms_settings_startupapps&quot; target=&quot;_blank&quot;&gt;启动应用&lt;/a&gt; 设置中被手动禁止。</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_AVAILABLE\" xml:space=\"preserve\">\n    <value>PowerToys 有版本更新。</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_UPDATE_NOW\" xml:space=\"preserve\">\n    <value>立刻更新</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_AVAILABLE_OFFER_VISIT\" xml:space=\"preserve\">\n    <value>PowerToys 有版本更新，请访问 GitHub 页面下载。</value>\n  </data>\n  <data name=\"GITHUB_NEW_VERSION_MORE_INFO\" xml:space=\"preserve\">\n    <value>更多信息</value>\n  </data>\n  <data name=\"TOAST_TITLE\" xml:space=\"preserve\">\n    <value>PowerToys 更新</value>\n  </data>\n  <data name=\"QUICK_ACCESS_MENU_TEXT\" xml:space=\"preserve\">\n    <value>快捷面板\\t单击图标</value>\n    <comment>Don't localize \"\\t\" as that is what separates the click portion to be right aligned in the menu.</comment>\n  </data>\n  <data name=\"SETTINGS_MENU_TEXT\" xml:space=\"preserve\">\n    <value>设置\\t双击图标</value>\n    <comment>Don't localize \"\\t\" as that is what separates the click portion to be right aligned in the menu.</comment>\n  </data>\n  <data name=\"DOCUMENTATION_MENU_TEXT\" xml:space=\"preserve\">\n    <value>帮助</value>\n  </data>\n  <data name=\"EXIT_MENU_TEXT\" xml:space=\"preserve\">\n    <value>退出</value>\n    <comment>Exit as a verb, as in Exit the application</comment>\n  </data>\n  <data name=\"SUBMIT_BUG_TEXT\" xml:space=\"preserve\">\n    <value>报告</value>\n  </data>\n  <data name=\"BUGREPORT_SUCCESS\" xml:space=\"preserve\">\n    <value>问题报告已打包为 Zip 文件放在桌面上了。</value>\n  </data>\n  <data name=\"PT_VERSION_CHANGE_ASK_FOR_COMPUTER_RESTART\" xml:space=\"preserve\">\n    <value>PowerToys 新版本安装完成，由于程序文件路径变更，需要重启电脑，来重新加载文件管理器集成功能。</value>\n    <comment>File Explorer refers to the Windows File Explorer application.</comment>\n  </data>\n  <data name=\"TRAY_ICON_ADMIN_TOOLTIP\" xml:space=\"preserve\">\n    <value>管理员权限</value>\n  </data>\n</root>\n"
  },
  {
    "path": "PowerToys/src/runner/main.cpp",
    "content": "#include \"pch.h\"\n#include <ShellScalingApi.h>\n#include <lmcons.h>\n#include <filesystem>\n#include <sstream>\n#include \"tray_icon.h\"\n#include \"powertoy_module.h\"\n#include \"trace.h\"\n#include \"general_settings.h\"\n#include \"restart_elevated.h\"\n#include \"RestartManagement.h\"\n#include \"Generated files/resource.h\"\n#include \"settings_telemetry.h\"\n\n#include <common/comUtils/comUtils.h>\n#include <common/display/dpi_aware.h>\n#include <common/Telemetry/EtwTrace/EtwTrace.h>\n#include <common/notifications/notifications.h>\n#include <common/notifications/dont_show_again.h>\n#include <common/updating/installer.h>\n#include <common/updating/updating.h>\n#include <common/updating/updateState.h>\n#include <common/utils/appMutex.h>\n#include <common/utils/elevation.h>\n#include <common/utils/os-detect.h>\n#include <common/utils/processApi.h>\n#include <common/utils/resources.h>\n#include <common/utils/clean_video_conference.h>\n\n#include \"UpdateUtils.h\"\n#include \"ActionRunnerUtils.h\"\n\n#include <winrt/Windows.System.h>\n\n#include <Psapi.h>\n#include <RestartManager.h>\n#include \"centralized_kb_hook.h\"\n#include \"centralized_hotkeys.h\"\n\n#if _DEBUG && _WIN64\n#include \"unhandled_exception_handler.h\"\n#endif\n#include <common/logger/logger.h>\n#include <common/SettingsAPI/settings_helpers.h>\n#include <runner/settings_window.h>\n#include <common/utils/process_path.h>\n#include <common/utils/winapi_error.h>\n#include <common/utils/window.h>\n#include <common/version/version.h>\n#include <common/utils/string_utils.h>\n#include <common/utils/gpo.h>\n\n// disabling warning 4458 - declaration of 'identifier' hides class member\n// to avoid warnings from GDI files - can't add winRT directory to external code\n// in the Cpp.Build.props\n#pragma warning(push)\n#pragma warning(disable : 4458)\n#include <gdiplus.h>\n#pragma warning(pop)\n\nnamespace\n{\n    const wchar_t PT_URI_PROTOCOL_SCHEME[] = L\"powertoys://\";\n    const wchar_t POWER_TOYS_MODULE_LOAD_FAIL[] = L\"无法加载 \"; // Module name will be appended on this message and it is not localized.\n}\n\nvoid chdir_current_executable()\n{\n    // Change current directory to the path of the executable.\n    WCHAR executable_path[MAX_PATH];\n    GetModuleFileName(NULL, executable_path, MAX_PATH);\n    PathRemoveFileSpec(executable_path);\n    if (!SetCurrentDirectory(executable_path))\n    {\n        show_last_error_message(L\"Change Directory to Executable Path\", GetLastError(), L\"PowerToys - runner\");\n    }\n}\n\ninline wil::unique_mutex_nothrow create_msi_mutex()\n{\n    return createAppMutex(POWERTOYS_MSI_MUTEX_NAME);\n}\n\nvoid open_menu_from_another_instance(std::optional<std::string> settings_window)\n{\n    const HWND hwnd_main = FindWindowW(L\"PToyTrayIconWindow\", nullptr);\n    LPARAM msg = static_cast<LPARAM>(ESettingsWindowNames::Dashboard);\n    if (settings_window.has_value() && settings_window.value() != \"\")\n    {\n        msg = static_cast<LPARAM>(ESettingsWindowNames_from_string(settings_window.value()));\n    }\n    PostMessageW(hwnd_main, WM_COMMAND, ID_SETTINGS_MENU_COMMAND, msg);\n}\n\nint runner(bool isProcessElevated, bool openSettings, std::string settingsWindow, bool openOobe, bool openScoobe, bool showRestartNotificationAfterUpdate)\n{\n    Logger::info(\"Runner is starting. Elevated={} openOobe={} openScoobe={} showRestartNotificationAfterUpdate={}\", isProcessElevated, openOobe, openScoobe, showRestartNotificationAfterUpdate);\n    DPIAware::EnableDPIAwarenessForThisProcess();\n\n#if _DEBUG && _WIN64\n//Global error handlers to diagnose errors.\n//We prefer this not to show any longer until there's a bug to diagnose.\n//init_global_error_handlers();\n#endif\n    Trace::RegisterProvider();\n    start_tray_icon(isProcessElevated);\n    CentralizedKeyboardHook::Start();\n\n    int result = -1;\n    try\n    {\n        if (!openOobe && showRestartNotificationAfterUpdate)\n        {\n            std::thread{\n                [] {\n                    // Wait a bit, because Windows has a delay until it picks up toast notification registration in the registry\n                    Sleep(10000);\n                    Logger::info(\"Showing toast notification asking to restart PC\");\n                    notifications::show_toast(GET_RESOURCE_STRING(IDS_PT_VERSION_CHANGE_ASK_FOR_COMPUTER_RESTART).c_str(), L\"PowerToys\");\n                }\n            }.detach();\n        }\n\n        std::thread{ [] {\n            PeriodicUpdateWorker();\n        } }.detach();\n\n        std::thread{ [] {\n            if (updating::uninstall_previous_msix_version_async().get())\n            {\n                notifications::show_toast(GET_RESOURCE_STRING(IDS_OLDER_MSIX_UNINSTALLED).c_str(), L\"PowerToys\");\n            }\n        } }.detach();\n\n        chdir_current_executable();\n\n        // We deprecated a utility called Video Conference Mute, which registered itself as a video input device.\n        // When running elevated, we try to clean up the device registration from previous installations.\n        // This is done here too because a user-scope installer won't be able to remove the driver registration due to lack of permissions.\n        if (isProcessElevated)\n        {\n            clean_video_conference();\n        }\n\n        // Load PowerToys DLLs\n\n        std::vector<std::wstring_view> knownModules = {\n            L\"PowerToys.FancyZonesModuleInterface.dll\",\n            L\"PowerToys.powerpreview.dll\",\n            L\"PowerToys.ImageResizerExt.dll\",\n            L\"PowerToys.KeyboardManager.dll\",\n            L\"PowerToys.Launcher.dll\",\n            L\"WinUI3Apps/PowerToys.PowerRenameExt.dll\",\n            L\"PowerToys.ShortcutGuideModuleInterface.dll\",\n            L\"PowerToys.ColorPicker.dll\",\n            L\"PowerToys.AwakeModuleInterface.dll\",\n            L\"PowerToys.FindMyMouse.dll\",\n            L\"PowerToys.MouseHighlighter.dll\",\n            L\"PowerToys.MouseJump.dll\",\n            L\"PowerToys.AlwaysOnTopModuleInterface.dll\",\n            L\"PowerToys.MousePointerCrosshairs.dll\",\n            L\"PowerToys.PowerAccentModuleInterface.dll\",\n            L\"PowerToys.PowerOCRModuleInterface.dll\",\n            L\"PowerToys.AdvancedPasteModuleInterface.dll\",\n            L\"WinUI3Apps/PowerToys.FileLocksmithExt.dll\",\n            L\"WinUI3Apps/PowerToys.RegistryPreviewExt.dll\",\n            L\"WinUI3Apps/PowerToys.MeasureToolModuleInterface.dll\",\n            L\"WinUI3Apps/PowerToys.NewPlus.ShellExtension.dll\",\n            L\"WinUI3Apps/PowerToys.HostsModuleInterface.dll\",\n            L\"WinUI3Apps/PowerToys.Peek.dll\",\n            L\"WinUI3Apps/PowerToys.EnvironmentVariablesModuleInterface.dll\",\n            L\"PowerToys.MouseWithoutBordersModuleInterface.dll\",\n            L\"PowerToys.CropAndLockModuleInterface.dll\",\n            L\"PowerToys.CmdNotFoundModuleInterface.dll\",\n            L\"PowerToys.WorkspacesModuleInterface.dll\",\n            L\"PowerToys.ZoomItModuleInterface.dll\",\n        };\n\n        for (auto moduleSubdir : knownModules)\n        {\n            try\n            {\n                auto pt_module = load_powertoy(moduleSubdir);\n                modules().emplace(pt_module->get_key(), std::move(pt_module));\n            }\n            catch (...)\n            {\n                std::wstring errorMessage = POWER_TOYS_MODULE_LOAD_FAIL;\n                errorMessage += moduleSubdir;\n                MessageBoxW(NULL,\n                            errorMessage.c_str(),\n                            L\"PowerToys\",\n                            MB_OK | MB_ICONERROR);\n            }\n        }\n        // Start initial powertoys\n        start_enabled_powertoys();\n        std::wstring product_version = get_product_version();\n        Trace::EventLaunch(product_version, isProcessElevated);\n        PTSettingsHelper::save_last_version_run(product_version);\n\n        if (openSettings)\n        {\n            std::optional<std::wstring> window;\n            if (!settingsWindow.empty())\n            {\n                window = winrt::to_hstring(settingsWindow);\n            }\n            open_settings_window(window, false);\n        }\n\n        if (openOobe)\n        {\n            PTSettingsHelper::save_oobe_opened_state();\n            open_oobe_window();\n        }\n        else if (openScoobe)\n        {\n            open_scoobe_window();\n        }\n\n        settings_telemetry::init();\n        result = run_message_loop();\n    }\n    catch (std::runtime_error& err)\n    {\n        std::string err_what = err.what();\n        MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR | MB_SETFOREGROUND);\n        result = -1;\n    }\n    Trace::UnregisterProvider();\n    return result;\n}\n\n// If the PT runner is launched as part of some action and manually by a user, e.g. being activated as a COM server\n// for background toast notification handling, we should execute corresponding code flow instead of the main code flow.\nenum class SpecialMode\n{\n    None,\n    Win32ToastNotificationCOMServer,\n    ToastNotificationHandler,\n    ReportSuccessfulUpdate\n};\n\nSpecialMode should_run_in_special_mode(const int n_cmd_args, LPWSTR* cmd_arg_list)\n{\n    for (size_t i = 1; i < n_cmd_args; ++i)\n    {\n        if (!wcscmp(notifications::TOAST_ACTIVATED_LAUNCH_ARG, cmd_arg_list[i]))\n        {\n            return SpecialMode::Win32ToastNotificationCOMServer;\n        }\n        else if (n_cmd_args == 2 && !wcsncmp(PT_URI_PROTOCOL_SCHEME, cmd_arg_list[i], wcslen(PT_URI_PROTOCOL_SCHEME)))\n        {\n            return SpecialMode::ToastNotificationHandler;\n        }\n        else if (n_cmd_args == 2 && !wcscmp(cmdArg::UPDATE_REPORT_SUCCESS, cmd_arg_list[i]))\n        {\n            return SpecialMode::ReportSuccessfulUpdate;\n        }\n    }\n\n    return SpecialMode::None;\n}\n\nint win32_toast_notification_COM_server_mode()\n{\n    notifications::run_desktop_app_activator_loop();\n    return 0;\n}\n\nenum class toast_notification_handler_result\n{\n    exit_success,\n    exit_error\n};\n\ntoast_notification_handler_result toast_notification_handler(const std::wstring_view param)\n{\n    const std::wstring_view cant_drag_elevated_disable = L\"cant_drag_elevated_disable/\";\n    const std::wstring_view couldnt_toggle_powerpreview_modules_disable = L\"couldnt_toggle_powerpreview_modules_disable/\";\n    const std::wstring_view open_settings = L\"open_settings/\";\n    const std::wstring_view open_overview = L\"open_overview/\";\n    const std::wstring_view update_now = L\"update_now/\";\n\n    if (param == cant_drag_elevated_disable)\n    {\n        return notifications::disable_toast(notifications::ElevatedDontShowAgainRegistryPath) ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error;\n    }\n    else if (param.starts_with(update_now))\n    {\n        std::wstring args{ cmdArg::UPDATE_NOW_LAUNCH_STAGE1 };\n        LaunchPowerToysUpdate(args.c_str());\n        return toast_notification_handler_result::exit_success;\n    }\n    else if (param == couldnt_toggle_powerpreview_modules_disable)\n    {\n        return notifications::disable_toast(notifications::PreviewModulesDontShowAgainRegistryPath) ? toast_notification_handler_result::exit_success : toast_notification_handler_result::exit_error;\n    }\n    else if (param == open_settings)\n    {\n        open_menu_from_another_instance(std::nullopt);\n        return toast_notification_handler_result::exit_success;\n    }\n    else if (param == open_overview)\n    {\n        open_menu_from_another_instance(\"Overview\");\n        return toast_notification_handler_result::exit_success;\n    }\n    else\n    {\n        return toast_notification_handler_result::exit_error;\n    }\n}\n\nint WINAPI WinMain(HINSTANCE /*hInstance*/, HINSTANCE /*hPrevInstance*/, LPSTR lpCmdLine, int /*nCmdShow*/)\n{\n    Shared::Trace::ETWTrace trace{};\n    trace.UpdateState(true);\n\n    Gdiplus::GdiplusStartupInput gpStartupInput;\n    ULONG_PTR gpToken;\n    GdiplusStartup(&gpToken, &gpStartupInput, NULL);\n\n    winrt::init_apartment();\n    const wchar_t* securityDescriptor =\n        L\"O:BA\" // Owner: Builtin (local) administrator\n        L\"G:BA\" // Group: Builtin (local) administrator\n        L\"D:\"\n        L\"(A;;0x7;;;PS)\" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Personal self\n        L\"(A;;0x7;;;IU)\" // Access allowed on COM_RIGHTS_EXECUTE for Interactive Users\n        L\"(A;;0x3;;;SY)\" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Local system\n        L\"(A;;0x7;;;BA)\" // Access allowed on COM_RIGHTS_EXECUTE, _LOCAL, & _REMOTE for Builtin (local) administrator\n        L\"(A;;0x3;;;S-1-15-3-1310292540-1029022339-4008023048-2190398717-53961996-4257829345-603366646)\" // Access allowed on COM_RIGHTS_EXECUTE, & _LOCAL for Win32WebViewHost package capability\n        L\"S:\"\n        L\"(ML;;NX;;;LW)\"; // Integrity label on No execute up for Low mandatory level\n    initializeCOMSecurity(securityDescriptor);\n\n    int n_cmd_args = 0;\n    LPWSTR* cmd_arg_list = CommandLineToArgvW(GetCommandLineW(), &n_cmd_args);\n    switch (should_run_in_special_mode(n_cmd_args, cmd_arg_list))\n    {\n    case SpecialMode::Win32ToastNotificationCOMServer:\n        return win32_toast_notification_COM_server_mode();\n    case SpecialMode::ToastNotificationHandler:\n        switch (toast_notification_handler(cmd_arg_list[1] + wcslen(PT_URI_PROTOCOL_SCHEME)))\n        {\n        case toast_notification_handler_result::exit_error:\n            return 1;\n        case toast_notification_handler_result::exit_success:\n            return 0;\n        }\n        [[fallthrough]];\n    case SpecialMode::ReportSuccessfulUpdate:\n    {\n        notifications::remove_toasts_by_tag(notifications::UPDATING_PROCESS_TOAST_TAG);\n        notifications::remove_all_scheduled_toasts();\n        notifications::show_toast(GET_RESOURCE_STRING(IDS_PT_UPDATE_MESSAGE_BOX_TEXT),\n                                  L\"PowerToys\",\n                                  notifications::toast_params{ notifications::UPDATING_PROCESS_TOAST_TAG });\n        break;\n    }\n\n    case SpecialMode::None:\n        // continue as usual\n        break;\n    }\n\n    std::filesystem::path logFilePath(PTSettingsHelper::get_root_save_folder_location());\n    logFilePath.append(LogSettings::runnerLogPath);\n    Logger::init(LogSettings::runnerLoggerName, logFilePath.wstring(), PTSettingsHelper::get_log_settings_file_location());\n\n    const std::string cmdLine{ lpCmdLine };\n    Logger::info(\"Running powertoys with cmd args: {}\", cmdLine);\n\n    auto open_settings_it = cmdLine.find(\"--open-settings\");\n    const bool open_settings = open_settings_it != std::string::npos;\n    // Check if opening specific settings window\n    open_settings_it = cmdLine.find(\"--open-settings=\");\n    std::string settings_window;\n    if (open_settings_it != std::string::npos)\n    {\n        std::string rest_of_cmd_line{ cmdLine, open_settings_it + std::string{ \"--open-settings=\" }.size() };\n        std::istringstream iss(rest_of_cmd_line);\n        iss >> settings_window;\n    }\n\n    // Check if another instance is already running.\n    wil::unique_mutex_nothrow msi_mutex = create_msi_mutex();\n    if (!msi_mutex)\n    {\n        open_menu_from_another_instance(settings_window);\n        return 0;\n    }\n\n    bool openOobe = false;\n    try\n    {\n        openOobe = !PTSettingsHelper::get_oobe_opened_state();\n    }\n    catch (const std::exception& e)\n    {\n        Logger::error(\"Failed to get or save OOBE state with an exception: {}\", e.what());\n    }\n\n    bool openScoobe = false;\n    bool showRestartNotificationAfterUpdate = false;\n    try\n    {\n        std::wstring last_version_run = PTSettingsHelper::get_last_version_run();\n        const auto product_version = get_product_version();\n        openScoobe = product_version != last_version_run;\n        showRestartNotificationAfterUpdate = openScoobe;\n        Logger::info(L\"Scoobe: product_version={} last_version_run={}\", product_version, last_version_run);\n    }\n    catch (const std::exception& e)\n    {\n        Logger::error(\"Failed to get last version with an exception: {}\", e.what());\n    }\n\n    int result = 0;\n    try\n    {\n        // Singletons initialization order needs to be preserved, first events and\n        // then modules to guarantee the reverse destruction order.\n        modules();\n\n        std::thread{ [] {\n            auto state = UpdateState::read();\n            if (state.state == UpdateState::upToDate)\n            {\n                updating::cleanup_updates();\n            }\n        } }.detach();\n\n        auto general_settings = load_general_settings();\n\n        // Apply the general settings but don't save it as the modules() variable has not been loaded yet\n        apply_general_settings(general_settings, false);\n        const bool elevated = is_process_elevated();\n        const bool with_dont_elevate_arg = cmdLine.find(\"--dont-elevate\") != std::string::npos;\n        const bool run_elevated_setting = general_settings.GetNamedBoolean(L\"run_elevated\", false);\n        const bool with_restartedElevated_arg = cmdLine.find(\"--restartedElevated\") != std::string::npos;\n\n        // Update scoobe behavior based on setting and gpo\n        bool scoobeSettingDisabled = general_settings.GetNamedBoolean(L\"show_whats_new_after_updates\", true) == false;\n        bool scoobeDisabledByGpo = powertoys_gpo::getDisableShowWhatsNewAfterUpdatesValue() == powertoys_gpo::gpo_rule_configured_enabled;\n        if (openScoobe && (scoobeSettingDisabled || scoobeDisabledByGpo))\n        {\n            // Scoobe should show after an update, but is disabled by policy or setting\n            Logger::info(L\"Scoobe: Showing scoobe after updates is disabled by setting or by GPO.\");\n            openScoobe = false;\n        }\n\n        bool dataDiagnosticsDisabledByGpo = powertoys_gpo::getAllowDataDiagnosticsValue() == powertoys_gpo::gpo_rule_configured_disabled;\n        if (dataDiagnosticsDisabledByGpo)\n        {\n            Logger::info(L\"Data diagnostics: Data diagnostics is disabled by GPO.\");\n            PTSettingsHelper::save_data_diagnostics(false);\n        }\n\n        if (elevated && with_dont_elevate_arg && !run_elevated_setting)\n        {\n            Logger::info(\"Scheduling restart as non elevated\");\n            schedule_restart_as_non_elevated();\n            result = 0;\n        }\n        else if (elevated || !run_elevated_setting || with_dont_elevate_arg || (!elevated && with_restartedElevated_arg))\n        {\n            // The condition (!elevated && with_restartedElevated_arg) solves issue #19307. Restart elevated loop detected, running non-elevated\n            if (!elevated && with_restartedElevated_arg)\n            {\n                Logger::info(\"Restart as elevated failed. Running non-elevated.\");\n            }\n\n            result = runner(elevated, open_settings, settings_window, openOobe, openScoobe, showRestartNotificationAfterUpdate);\n\n            if (result == 0)\n            {\n                // Save settings on closing, if closed 'normal'\n                PTSettingsHelper::save_general_settings(get_general_settings().to_json());\n            }\n        }\n        else\n        {\n            Logger::info(\"Scheduling restart as elevated\");\n            schedule_restart_as_elevated(open_settings);\n            result = 0;\n        }\n    }\n    catch (std::runtime_error& err)\n    {\n        std::string err_what = err.what();\n        MessageBoxW(nullptr, std::wstring(err_what.begin(), err_what.end()).c_str(), GET_RESOURCE_STRING(IDS_ERROR).c_str(), MB_OK | MB_ICONERROR);\n        result = -1;\n    }\n\n    trace.Flush();\n    trace.UpdateState(false);\n\n    // We need to release the mutexes to be able to restart the application\n    if (msi_mutex)\n    {\n        msi_mutex.reset(nullptr);\n    }\n\n    if (is_restart_scheduled())\n    {\n        modules().clear();\n        if (!restart_if_scheduled())\n        {\n            // If it's not possible to restart non-elevated due to some condition in the user's configuration, user should start PowerToys manually.\n            Logger::warn(\"Scheduled restart failed. Couldn't restart non-elevated. PowerToys exits here because retrying it would just mean failing in a loop.\");\n        }\n    }\n    stop_tray_icon();\n    return result;\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/Assets/Settings/Scripts/CheckCmdNotFoundRequirements.ps1",
    "content": "Write-Host $PSVersionTable\nif ($PSVersionTable.PSVersion -ge 7.4)\n{\n  Write-Host \"已安装 PowerShell 7.4 或更高版本.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\nelse\n{\n  Write-Host \"未安装 PowerShell 7.4 或更高版本. 如需安装请访问 https://learn.microsoft.com/powershell/scripting/install/installing-powershell-on-windows `r`n\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\n\nif ($mods = Get-Module -ListAvailable -Name Microsoft.WinGet.Client)\n{\n  Write-Host \"已安装 WinGet 客户端模块.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n\n  $needsUpdate = $true;\n  foreach ($mod in $mods)\n  {\n    if ($mod.Version -ge \"1.8.1133\")\n    {\n      $needsUpdate = $false;\n      break;\n    }\n  }\n  if ($needsUpdate)\n  {\n    Write-Host \"WinGet 客户端模块需要更新.\"\n    # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n  }\n} \nelse {\n  Write-Host \"未安装 WinGet 客户端模块. 如需安装请访问 https://www.powershellgallery.com/packages/Microsoft.WinGet.Client `r`n\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\n\nif (!(Test-Path $PROFILE))\n{\n  Write-Host \"未发现配置文件 $PROFILE\".\n  New-Item -Path $PROFILE -ItemType File\n  Write-Host \"已创建配置文件 $PROFILE\".\n}\n\n$profileContent = Get-Content -Path $PROFILE -Raw\n\nif ((-not [string]::IsNullOrEmpty($profileContent)) -and ($profileContent.Contains(\"34de4b3d-13a8-4540-b76d-b9e8d3851756\")))\n{\n  Write-Host \"已在配置文件中注册旧版模块.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\nelseif ((-not [string]::IsNullOrEmpty($profileContent)) -and ($profileContent.Contains(\"f45873b3-b655-43a6-b217-97c00aa0db58\")))\n{\n  Write-Host \"已在配置文件中注册本模块.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\nelse\n{\n  Write-Host \"未在配置文件中注册本模块.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/Assets/Settings/Scripts/DisableModule.ps1",
    "content": "$profileContent = Get-Content $PROFILE\n\n$newContent = \"\"\n$linesToDeleteFound = $False\n$atLeastOneInstanceFound = $False\n\n$profileContent | ForEach-Object {\n  if (($_.Contains(\"34de4b3d-13a8-4540-b76d-b9e8d3851756\") -or $_.Contains(\"f45873b3-b655-43a6-b217-97c00aa0db58\")) -and !$linesToDeleteFound)\n  {\n    $linesToDeleteFound = $True\n    $atLeastOneInstanceFound = $True\n    return\n  }\n\n  if (($_.Contains(\"34de4b3d-13a8-4540-b76d-b9e8d3851756\") -or $_.Contains(\"f45873b3-b655-43a6-b217-97c00aa0db58\")) -and $linesToDeleteFound)\n  {\n    $linesToDeleteFound = $False\n    return\n  }\n\n  if($linesToDeleteFound)\n  {\n    return\n  }\n\n  $newContent += $_ + \"`r`n\"\n}\n\nif($atLeastOneInstanceFound)\n{\n  Set-Content -Path $PROFILE -Value $newContent\n  Write-Host \"已从配置文件中删除本模块.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n} else {\n  Write-Host \"配置文件中没有发现本模块, 不需要删除.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/Assets/Settings/Scripts/EnableModule.ps1",
    "content": "[CmdletBinding()]\nParam(\n  [Parameter(Mandatory=$True,Position=1)]\n  [string]$scriptPath\n)\n\nWrite-Host \"Enabling experimental feature: PSFeedbackProvider\"\nEnable-ExperimentalFeature PSFeedbackProvider\nWrite-Host \"Enabling experimental feature: PSCommandNotFoundSuggestion\"\nEnable-ExperimentalFeature PSCommandNotFoundSuggestion\n\n$wingetModules = Get-Module -ListAvailable -Name Microsoft.WinGet.Client\nif ($wingetModules) {\n\n  $moduleUpToDate = $false;\n  foreach ($mod in $wingetModules) {\n    if ($mod.Version -ge \"1.8.1133\") {\n      $moduleUpToDate = $true;\n      break;\n    }\n  }\n\n  if ($moduleUpToDate) {\n    Write-Host \"已安装 WinGet 客户端模块\"\n  } else {\n    Write-Host \"WinGet 客户端模块需要更新. 运行 `\"Update-Module -Name Microsoft.WinGet.Client`\" 来更新 `r`n\"\n  }\n} \nelse {\n    Write-Host \"未安装 WinGet 客户端模块. 如需安装请访问 https://www.powershellgallery.com/packages/Microsoft.WinGet.Client `r`n\"\n}\n\n$CNFModule = Get-Module -ListAvailable -Name Microsoft.WinGet.CommandNotFound\nif ($CNFModule) {\n  Write-Host \"已安装 Microsoft.WinGet.CommandNotFound 模块\"\n} else {\n  Write-Host \"未安装 Microsoft.WinGet.CommandNotFound 模块. 正在安装它...`r`n\"\n  Install-Module -Name Microsoft.WinGet.CommandNotFound -Force\n  Write-Host \"成功安装 Microsoft.WinGet.CommandNotFound 模块`r`n\"\n}\n\nif (!(Test-Path $PROFILE))\n{\n  Write-Host \"未发现配置文件 $PROFILE\".\n  New-Item -Path $PROFILE -ItemType File\n  Write-Host \"已创建配置文件 $PROFILE\".\n}\n\n$profileContent = Get-Content -Path $PROFILE -Raw\n\nif ((-not [string]::IsNullOrEmpty($profileContent)) -and ($profileContent.Contains(\"34de4b3d-13a8-4540-b76d-b9e8d3851756\")))\n{\n  if ($profileContent.Contains(\"Import-Module `\"$scriptPath\\WinGetCommandNotFound.psd1`\"\"))\n  {\n    $profileContent = $profileContent.Replace(\"Import-Module `\"$scriptPath\\WinGetCommandNotFound.psd1`\"\",\n                                              \"Import-Module -Name Microsoft.WinGet.CommandNotFound\")\n    $profileContent = $profileContent.Replace(\"34de4b3d-13a8-4540-b76d-b9e8d3851756\",\n                                              \"f45873b3-b655-43a6-b217-97c00aa0db58\")\n    Set-Content -Path $PROFILE -Value $profileContent\n    Write-Host \"成功在配置文件中更新模块.\"\n    # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n  }\n}\nelseif ((-not [string]::IsNullOrEmpty($profileContent)) -and ($profileContent.Contains(\"f45873b3-b655-43a6-b217-97c00aa0db58\")))\n{\n  Write-Host \"发现模块已经在配置文件中注册过了.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\nelse\n{\n  Add-Content -Path $PROFILE  -Value \"`r`n#f45873b3-b655-43a6-b217-97c00aa0db58 PowerToys CommandNotFound module\"\n  Add-Content -Path $PROFILE  -Value \"`r`nImport-Module -Name Microsoft.WinGet.CommandNotFound\"\n  Add-Content -Path $PROFILE  -Value \"#f45873b3-b655-43a6-b217-97c00aa0db58\"  \n  Write-Host \"成功在配置文件中注册模块.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/Assets/Settings/Scripts/InstallPowerShell7.ps1",
    "content": "\nif ((Get-AppxPackage microsoft.DesktopAppInstaller).Version -ge [System.Version]\"1.21\")\n{\n  Write-Host \"已安装 winget, 即将开始安装 PowerShell.\"\n}\nelse\n{\n  Write-Host \"未安装 WinGet, 即将开始安装它.\"\n  # To speed up Invoke-WebRequest. Older versions are very slow when printing the progress.\n  $ProgressPreference = 'SilentlyContinue'\n  $cpuArchitecture=\"x64\"\n  $detectedArchitecture=\"\"\n  if ($env:PROCESSOR_ARCHITEW6432 -eq $null) {\n    $detectedArchitecture=$env:PROCESSOR_ARCHITECTURE\n  } else {\n    $detectedArchitecture=$env:PROCESSOR_ARCHITEW6432\n  }\n  Write-Host \"CPU 架构: $detectedArchitecture\"\n  if ($detectedArchitecture -ne \"AMD64\")\n  {\n    Write-Host \"不属于 AMD64, 判定为 arm64, 因为这是本软件通常所处的环境.\"\n    $cpuArchitecture=\"arm64\"\n  }\n  if((Get-AppxPackage Microsoft.VCLibs.140.00).Version -ge [System.Version]\"14.0.30704\")\n  {\n    Write-Host \"已安装 Microsoft.VCLibs.140.00.\"\n  }\n  else\n  {\n    Write-Host \"未安装 Microsoft.VCLibs.140.00, 即将开始安装它.\"\n    Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.$cpuArchitecture.14.00.Desktop.appx -OutFile \"$Env:TMP\\Microsoft.VCLibs.14.00.appx\"\n    Add-AppxPackage -Path \"$Env:TMP\\Microsoft.VCLibs.14.00.appx\"\n    Remove-Item -Path \"$Env:TMP\\Microsoft.VCLibs.14.00.appx\" -Force\n  }\n  if((Get-AppxPackage Microsoft.VCLibs.140.00.UWPDesktop).Version -ge [System.Version]\"14.0.30704\")\n  {\n    Write-Host \"已安装 Microsoft.VCLibs.140.00.UWPDesktop\"\n  }\n  else\n  {\n    Write-Host \"未安装 Microsoft.VCLibs.140.00.UWPDesktop, 即将开始安装它.\"\n    Invoke-WebRequest -Uri https://aka.ms/Microsoft.VCLibs.$cpuArchitecture.14.00.Desktop.appx -OutFile \"$Env:TMP\\Microsoft.VCLibs.14.00.Desktop.appx\"\n    Add-AppxPackage -Path \"$Env:TMP\\Microsoft.VCLibs.14.00.Desktop.appx\"\n    Remove-Item -Path \"$Env:TMP\\Microsoft.VCLibs.14.00.Desktop.appx\" -Force\n  }\n  if (Get-AppxPackage Microsoft.UI.Xaml.2.7)\n  {\n    Write-Host \"已安装 Microsoft.UI.Xaml.2.7\"\n  }\n  else\n  {\n    Write-Host \"未安装 Microsoft.UI.Xaml.2.7, 即将开始安装它.\"\n    Write-Host \"正在下载到 $Env:TMP\\microsoft.ui.xaml.2.7.3.zip\"\n    Invoke-WebRequest -Uri https://www.nuget.org/api/v2/package/Microsoft.UI.Xaml/2.7.3 -OutFile \"$Env:TMP\\microsoft.ui.xaml.2.7.3.zip\"\n    Write-Host \"正在解压 $Env:TMP\\microsoft.ui.xaml.2.7.3.zip\"\n    Expand-Archive \"$Env:TMP\\microsoft.ui.xaml.2.7.3.zip\" -DestinationPath \"$Env:TMP\\microsoft.ui.xaml.2.7.3\"\n    Write-Host \"正在安装 $Env:TMP\\microsoft.ui.xaml.2.7.3\\tools\\AppX\\$cpuArchitecture\\Release\\Microsoft.UI.Xaml.2.7.appx\"\n    Add-AppxPackage \"$Env:TMP\\microsoft.ui.xaml.2.7.3\\tools\\AppX\\$cpuArchitecture\\Release\\Microsoft.UI.Xaml.2.7.appx\"\n    Remove-Item -Path \"$Env:TMP\\microsoft.ui.xaml.2.7.3\" -Recurse -Force\n    Remove-Item -Path \"$Env:TMP\\microsoft.ui.xaml.2.7.3.zip\" -Force\n  }\n  Write-Host \"正在获取最新稳定版的 winget\"\n  Invoke-WebRequest -Uri https://aka.ms/getwinget -OutFile \"$Env:TMP\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle\"\n  Add-AppxPackage -Path \"$Env:TMP\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle\"\n  Remove-Item -Path \"$Env:TMP\\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle\" -Force\n\n  #winget is not visible right away, so reload the PATH variable.\n  $env:Path = [System.Environment]::GetEnvironmentVariable(\"Path\",\"Machine\") + \";\" + [System.Environment]::GetEnvironmentVariable(\"Path\",\"User\") \n}\n\nwinget install Microsoft.PowerShell --source winget\nif ($LASTEXITCODE -eq 0)\n{\n  Write-Host \"成功安装 Powershell 7.\"\n  # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n}\nelse\n{\n  Write-Host \"未能成功安装 Powershell 7.\"\n}\n\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/Assets/Settings/Scripts/InstallWinGetClientModule.ps1",
    "content": "$wingetModules = Get-Module -ListAvailable -Name Microsoft.WinGet.Client\nif ($wingetModules)\n{\n  $needsUpdate = $true;\n  foreach ($mod in $wingetModules)\n  {\n    if ($mod.Version -ge \"1.8.1133\")\n    {\n      $needsUpdate = $false;\n      break;\n    }\n  }\n\n  if ($needsUpdate)\n  {\n    Update-Module -Name Microsoft.WinGet.Client -Force\n    $wingetModules = Get-Module -ListAvailable -Name Microsoft.WinGet.Client\n    $updated = $false;\n    foreach ($mod in $wingetModules)\n    {\n      if ($mod.Version -ge \"1.8.1133\")\n      {\n        $updated = $true;\n        break;\n      }\n    }\n\n    if ($updated)\n    {\n      Write-Host \"已更新 WinGet 客户端模块.\"\n        # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n    }\n    else\n    {\n      Write-Host \"已安装 WinGet 客户端模块.\"\n      # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n    }\n  }\n  else\n  {\n    Write-Host \"已安装 WinGet 客户端模块.\"\n    # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n  }\n} \nelse {\n  Install-Module -Name Microsoft.WinGet.Client\n  if (Get-Module -ListAvailable -Name Microsoft.WinGet.Client)\n  {\n    Write-Host \"已安装 WinGet 客户端模块.\"\n    # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n  } else {\n    Write-Host \"未安装 WinGet 客户端模块. 如需安装请访问 https://www.powershellgallery.com/packages/Microsoft.WinGet.Client `r`n\"\n    # This message will be compared against in Command Not Found Settings page code behind. Take care when changing it.\n  }\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/Converters/ZoomItTypeSpeedSliderConverter.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing Microsoft.PowerToys.Settings.UI.Helpers;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Microsoft.UI.Xaml.Data;\n\nnamespace Microsoft.PowerToys.Settings.UI.Converters\n{\n    public sealed partial class ZoomItTypeSpeedSliderConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter, string language)\n        {\n            string targetValue = string.Empty;\n            int zoomLevel = System.Convert.ToInt32((double)value);\n            string explanation = ResourceLoaderInstance.ResourceLoader.GetString(\"ZoomIt_DemoType_SpeedSlider_Thumbnail_Explanation\");\n\n            targetValue = $\"{zoomLevel}（{explanation}）\";\n\n            return targetValue;\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, string language) => throw new NotImplementedException();\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/App.xaml.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Text.Json;\nusing System.Threading.Tasks;\n\nusing ManagedCommon;\nusing Microsoft.PowerToys.Settings.UI.Helpers;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;\nusing Microsoft.PowerToys.Settings.UI.Services;\nusing Microsoft.PowerToys.Settings.UI.Views;\nusing Microsoft.PowerToys.Telemetry;\nusing Microsoft.UI.Xaml;\nusing PowerToys.Interop;\nusing Windows.UI.Popups;\nusing WinRT.Interop;\nusing WinUIEx;\n\nnamespace Microsoft.PowerToys.Settings.UI\n{\n    /// <summary>\n    /// Provides application-specific behavior to supplement the default Application class.\n    /// </summary>\n    public partial class App : Application\n    {\n        private enum Arguments\n        {\n            PTPipeName = 1,\n            SettingsPipeName,\n            PTPid,\n            Theme, // used in the old settings\n            ElevatedStatus,\n            IsUserAdmin,\n            ShowOobeWindow,\n            ShowScoobeWindow,\n            ShowFlyout,\n            ContainsSettingsWindow,\n            ContainsFlyoutPosition,\n        }\n\n        private const int RequiredArgumentsSetSettingQty = 4;\n        private const int RequiredArgumentsSetAdditionalSettingsQty = 4;\n        private const int RequiredArgumentsGetSettingQty = 3;\n\n        private const int RequiredArgumentsLaunchedFromRunnerQty = 12;\n\n        // Create an instance of the  IPC wrapper.\n        private static TwoWayPipeMessageIPCManaged ipcmanager;\n\n        public static bool IsElevated { get; set; }\n\n        public static bool IsUserAnAdmin { get; set; }\n\n        public static int PowerToysPID { get; set; }\n\n        public bool ShowOobe { get; set; }\n\n        public bool ShowFlyout { get; set; }\n\n        public bool ShowScoobe { get; set; }\n\n        public Type StartupPage { get; set; } = typeof(Views.DashboardPage);\n\n        public static Action<string> IPCMessageReceivedCallback { get; set; }\n\n        public ETWTrace EtwTrace { get; private set; } = new ETWTrace();\n\n        /// <summary>\n        /// Initializes a new instance of the <see cref=\"App\"/> class.\n        /// Initializes the singleton application object. This is the first line of authored code\n        /// executed, and as such is the logical equivalent of main() or WinMain().\n        /// </summary>\n        public App()\n        {\n            Logger.InitializeLogger(@\"\\Settings\\Logs\");\n\n            string appLanguage = LanguageHelper.LoadLanguage();\n            if (!string.IsNullOrEmpty(appLanguage))\n            {\n                Microsoft.Windows.Globalization.ApplicationLanguages.PrimaryLanguageOverride = appLanguage;\n            }\n\n            InitializeComponent();\n\n            UnhandledException += App_UnhandledException;\n\n            NativeEventWaiter.WaitForEventLoop(\n                Constants.PowerToysRunnerTerminateSettingsEvent(), () =>\n            {\n                EtwTrace?.Dispose();\n                Environment.Exit(0);\n            });\n        }\n\n        private void App_UnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)\n        {\n            Logger.LogError(\"Unhandled exception\", e.Exception);\n        }\n\n        public static void OpenSettingsWindow(Type type = null, bool ensurePageIsSelected = false)\n        {\n            if (settingsWindow == null)\n            {\n                settingsWindow = new MainWindow();\n            }\n\n            settingsWindow.Activate();\n\n            if (type != null)\n            {\n                settingsWindow.NavigateToSection(type);\n\n                WindowHelpers.BringToForeground(settingsWindow.GetWindowHandle());\n            }\n\n            if (ensurePageIsSelected)\n            {\n                settingsWindow.EnsurePageIsSelected();\n            }\n        }\n\n        private void OnLaunchedToSetSetting(string[] cmdArgs)\n        {\n            var settingName = cmdArgs[2];\n            var settingValue = cmdArgs[3];\n            try\n            {\n                SetSettingCommandLineCommand.Execute(settingName, settingValue, new SettingsUtils());\n            }\n            catch (Exception ex)\n            {\n                Logger.LogError($\"SetSettingCommandLineCommand exception: '{settingName}' setting couldn't be set to {settingValue}\", ex);\n            }\n\n            Exit();\n        }\n\n        private void OnLaunchedToSetAdditionalSetting(string[] cmdArgs)\n        {\n            var moduleName = cmdArgs[2];\n            var ipcFileName = cmdArgs[3];\n            try\n            {\n                using (var settings = JsonDocument.Parse(File.ReadAllText(ipcFileName)))\n                {\n                    SetAdditionalSettingsCommandLineCommand.Execute(moduleName, settings, new SettingsUtils());\n                }\n            }\n            catch (Exception ex)\n            {\n                Logger.LogError($\"SetAdditionalSettingsCommandLineCommand exception: couldn't set additional settings for '{moduleName}'\", ex);\n            }\n\n            Exit();\n        }\n\n        private void OnLaunchedToGetSetting(string[] cmdArgs)\n        {\n            var ipcFileName = cmdArgs[2];\n\n            try\n            {\n                var requestedSettings = JsonSerializer.Deserialize<Dictionary<string, List<string>>>(File.ReadAllText(ipcFileName));\n                File.WriteAllText(ipcFileName, GetSettingCommandLineCommand.Execute(requestedSettings));\n            }\n            catch (Exception ex)\n            {\n                Logger.LogError($\"GetSettingCommandLineCommand exception\", ex);\n            }\n\n            Exit();\n        }\n\n        private void OnLaunchedFromRunner(string[] cmdArgs)\n        {\n            // Skip the first argument which is prepended when launched by explorer\n            if (cmdArgs[0].EndsWith(\".dll\", StringComparison.InvariantCultureIgnoreCase) && cmdArgs[1].EndsWith(\".exe\", StringComparison.InvariantCultureIgnoreCase) && (cmdArgs.Length >= RequiredArgumentsLaunchedFromRunnerQty + 1))\n            {\n                cmdArgs = cmdArgs.Skip(1).ToArray();\n            }\n\n            _ = int.TryParse(cmdArgs[(int)Arguments.PTPid], out int powerToysPID);\n            PowerToysPID = powerToysPID;\n\n            IsElevated = cmdArgs[(int)Arguments.ElevatedStatus] == \"true\";\n            IsUserAnAdmin = cmdArgs[(int)Arguments.IsUserAdmin] == \"true\";\n            ShowOobe = cmdArgs[(int)Arguments.ShowOobeWindow] == \"true\";\n            ShowScoobe = cmdArgs[(int)Arguments.ShowScoobeWindow] == \"true\";\n            ShowFlyout = cmdArgs[(int)Arguments.ShowFlyout] == \"true\";\n            bool containsSettingsWindow = cmdArgs[(int)Arguments.ContainsSettingsWindow] == \"true\";\n            bool containsFlyoutPosition = cmdArgs[(int)Arguments.ContainsFlyoutPosition] == \"true\";\n\n            // To keep track of variable arguments\n            int currentArgumentIndex = RequiredArgumentsLaunchedFromRunnerQty;\n\n            if (containsSettingsWindow)\n            {\n                // Open specific window\n                StartupPage = GetPage(cmdArgs[currentArgumentIndex]);\n\n                currentArgumentIndex++;\n            }\n\n            int flyout_x = 0;\n            int flyout_y = 0;\n            if (containsFlyoutPosition)\n            {\n                // get the flyout position arguments\n                _ = int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_x);\n                _ = int.TryParse(cmdArgs[currentArgumentIndex++], out flyout_y);\n            }\n\n            RunnerHelper.WaitForPowerToysRunner(PowerToysPID, () =>\n            {\n                Environment.Exit(0);\n            });\n\n            ipcmanager = new TwoWayPipeMessageIPCManaged(cmdArgs[(int)Arguments.SettingsPipeName], cmdArgs[(int)Arguments.PTPipeName], (string message) =>\n            {\n                if (IPCMessageReceivedCallback != null && message.Length > 0)\n                {\n                    IPCMessageReceivedCallback(message);\n                }\n            });\n            ipcmanager.Start();\n\n            if (!ShowOobe && !ShowScoobe && !ShowFlyout)\n            {\n                settingsWindow = new MainWindow();\n                settingsWindow.Activate();\n                settingsWindow.ExtendsContentIntoTitleBar = true;\n                settingsWindow.NavigateToSection(StartupPage);\n\n                // https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground\n                // Need to call SetForegroundWindow to actually gain focus.\n                WindowHelpers.BringToForeground(settingsWindow.GetWindowHandle());\n\n                // https://github.com/microsoft/microsoft-ui-xaml/issues/8948 - A window's top border incorrectly\n                // renders as black on Windows 10.\n                WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));\n            }\n            else\n            {\n                // Create the Settings window hidden so that it's fully initialized and\n                // it will be ready to receive the notification if the user opens\n                // the Settings from the tray icon.\n                settingsWindow = new MainWindow(true);\n\n                if (ShowOobe)\n                {\n                    PowerToysTelemetry.Log.WriteEvent(new OobeStartedEvent());\n                    OobeWindow oobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.Overview);\n                    oobeWindow.Activate();\n                    oobeWindow.ExtendsContentIntoTitleBar = true;\n                    WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));\n                    SetOobeWindow(oobeWindow);\n                }\n                else if (ShowScoobe)\n                {\n                    PowerToysTelemetry.Log.WriteEvent(new ScoobeStartedEvent());\n                    OobeWindow scoobeWindow = new OobeWindow(OOBE.Enums.PowerToysModules.WhatsNew);\n                    scoobeWindow.Activate();\n                    scoobeWindow.ExtendsContentIntoTitleBar = true;\n                    WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));\n                    SetOobeWindow(scoobeWindow);\n                }\n                else if (ShowFlyout)\n                {\n                    POINT? p = null;\n                    if (containsFlyoutPosition)\n                    {\n                        p = new POINT(flyout_x, flyout_y);\n                    }\n\n                    ShellPage.OpenFlyoutCallback(p);\n                }\n            }\n        }\n\n        /// <summary>\n        /// Invoked when the application is launched normally by the end user.  Other entry points\n        /// will be used such as when the application is launched to open a specific file.\n        /// </summary>\n        /// <param name=\"args\">Details about the launch request and process.</param>\n        protected override void OnLaunched(Microsoft.UI.Xaml.LaunchActivatedEventArgs args)\n        {\n            var cmdArgs = Environment.GetCommandLineArgs();\n\n            if (cmdArgs?.Length >= RequiredArgumentsLaunchedFromRunnerQty)\n            {\n                OnLaunchedFromRunner(cmdArgs);\n            }\n            else if (cmdArgs?.Length == RequiredArgumentsSetSettingQty && cmdArgs[1] == \"set\")\n            {\n                OnLaunchedToSetSetting(cmdArgs);\n            }\n            else if (cmdArgs?.Length == RequiredArgumentsSetAdditionalSettingsQty && cmdArgs[1] == \"setAdditional\")\n            {\n                OnLaunchedToSetAdditionalSetting(cmdArgs);\n            }\n            else if (cmdArgs?.Length == RequiredArgumentsGetSettingQty && cmdArgs[1] == \"get\")\n            {\n                OnLaunchedToGetSetting(cmdArgs);\n            }\n            else\n            {\n#if DEBUG\n                // For debugging purposes\n                // Window is also needed to show MessageDialog\n                settingsWindow = new MainWindow();\n                settingsWindow.ExtendsContentIntoTitleBar = true;\n                WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(settingsWindow));\n                settingsWindow.Activate();\n                settingsWindow.NavigateToSection(StartupPage);\n                ShowMessageDialog(\"软件正以调试模式运行.\", \"DEBUG\");\n#else\n                /* If we try to run Settings as a standalone app, it will start PowerToys.exe if not running and open Settings again through it in the Dashboard page. */\n                Common.UI.SettingsDeepLink.OpenSettings(Common.UI.SettingsDeepLink.SettingsWindow.Dashboard, true);\n                Exit();\n#endif\n            }\n        }\n\n#if !DEBUG\n        private async void ShowMessageDialogAndExit(string content, string title = null)\n#else\n        private async void ShowMessageDialog(string content, string title = null)\n#endif\n        {\n            await ShowDialogAsync(content, title);\n#if !DEBUG\n            this.Exit();\n#endif\n        }\n\n        public static Task<IUICommand> ShowDialogAsync(string content, string title = null)\n        {\n            var dialog = new MessageDialog(content, title ?? string.Empty);\n            var handle = NativeMethods.GetActiveWindow();\n            if (handle == IntPtr.Zero)\n            {\n                throw new InvalidOperationException();\n            }\n\n            InitializeWithWindow.Initialize(dialog, handle);\n            return dialog.ShowAsync().AsTask<IUICommand>();\n        }\n\n        public static TwoWayPipeMessageIPCManaged GetTwoWayIPCManager()\n        {\n            return ipcmanager;\n        }\n\n        public static bool IsDarkTheme()\n        {\n            return ThemeService.Theme == ElementTheme.Dark || (ThemeService.Theme == ElementTheme.Default && ThemeHelpers.GetAppTheme() == AppTheme.Dark);\n        }\n\n        public static int UpdateUIThemeMethod(string themeName)\n        {\n            return 0;\n        }\n\n        private static ISettingsUtils settingsUtils = new SettingsUtils();\n        private static ThemeService themeService = new ThemeService(SettingsRepository<GeneralSettings>.GetInstance(settingsUtils));\n\n        public static ThemeService ThemeService => themeService;\n\n        private static MainWindow settingsWindow;\n        private static OobeWindow oobeWindow;\n        private static FlyoutWindow flyoutWindow;\n\n        public static void ClearSettingsWindow()\n        {\n            settingsWindow = null;\n        }\n\n        public static MainWindow GetSettingsWindow()\n        {\n            return settingsWindow;\n        }\n\n        public static OobeWindow GetOobeWindow()\n        {\n            return oobeWindow;\n        }\n\n        public static FlyoutWindow GetFlyoutWindow()\n        {\n            return flyoutWindow;\n        }\n\n        public static void SetOobeWindow(OobeWindow window)\n        {\n            oobeWindow = window;\n        }\n\n        public static void SetFlyoutWindow(FlyoutWindow window)\n        {\n            flyoutWindow = window;\n        }\n\n        public static void ClearOobeWindow()\n        {\n            oobeWindow = null;\n        }\n\n        public static void ClearFlyoutWindow()\n        {\n            flyoutWindow = null;\n        }\n\n        public static Type GetPage(string settingWindow)\n        {\n            switch (settingWindow)\n            {\n                case \"Dashboard\": return typeof(DashboardPage);\n                case \"Overview\": return typeof(GeneralPage);\n                case \"AdvancedPaste\": return typeof(AdvancedPastePage);\n                case \"AlwaysOnTop\": return typeof(AlwaysOnTopPage);\n                case \"Awake\": return typeof(AwakePage);\n                case \"CmdNotFound\": return typeof(CmdNotFoundPage);\n                case \"ColorPicker\": return typeof(ColorPickerPage);\n                case \"FancyZones\": return typeof(FancyZonesPage);\n                case \"FileLocksmith\": return typeof(FileLocksmithPage);\n                case \"Run\": return typeof(PowerLauncherPage);\n                case \"ImageResizer\": return typeof(ImageResizerPage);\n                case \"KBM\": return typeof(KeyboardManagerPage);\n                case \"MouseUtils\": return typeof(MouseUtilsPage);\n                case \"MouseWithoutBorders\": return typeof(MouseWithoutBordersPage);\n                case \"PowerRename\": return typeof(PowerRenamePage);\n                case \"QuickAccent\": return typeof(PowerAccentPage);\n                case \"FileExplorer\": return typeof(PowerPreviewPage);\n                case \"ShortcutGuide\": return typeof(ShortcutGuidePage);\n                case \"PowerOcr\": return typeof(PowerOcrPage);\n                case \"MeasureTool\": return typeof(MeasureToolPage);\n                case \"Hosts\": return typeof(HostsPage);\n                case \"RegistryPreview\": return typeof(RegistryPreviewPage);\n                case \"Peek\": return typeof(PeekPage);\n                case \"CropAndLock\": return typeof(CropAndLockPage);\n                case \"EnvironmentVariables\": return typeof(EnvironmentVariablesPage);\n                case \"NewPlus\": return typeof(NewPlusPage);\n                case \"Workspaces\": return typeof(WorkspacesPage);\n                case \"ZoomIt\": return typeof(ZoomItPage);\n                default:\n                    // Fallback to Dashboard\n                    Debug.Assert(false, \"Unexpected SettingsWindow argument value\");\n                    return typeof(DashboardPage);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml",
    "content": "﻿<UserControl\n    x:Class=\"Microsoft.PowerToys.Settings.UI.OOBE.Views.OobeShellPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:animations=\"using:CommunityToolkit.WinUI.Animations\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    HighContrastAdjustment=\"None\"\n    Loaded=\"ShellPage_Loaded\"\n    mc:Ignorable=\"d\">\n\n    <Grid>\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"*\" />\n        </Grid.RowDefinitions>\n        <Button\n            x:Name=\"PaneToggleBtn\"\n            Width=\"48\"\n            HorizontalAlignment=\"Left\"\n            VerticalAlignment=\"Center\"\n            Click=\"PaneToggleBtn_Click\"\n            Style=\"{StaticResource PaneToggleButtonStyle}\" />\n        <Grid\n            x:Name=\"AppTitleBar\"\n            Height=\"48\"\n            Margin=\"48,0,0,0\"\n            VerticalAlignment=\"Center\"\n            IsHitTestVisible=\"True\">\n            <animations:Implicit.Animations>\n                <animations:OffsetAnimation Duration=\"0:0:0.3\" />\n            </animations:Implicit.Animations>\n            <StackPanel Orientation=\"Horizontal\">\n                <Image\n                    Width=\"16\"\n                    Height=\"16\"\n                    Source=\"/Assets/Settings/icon.ico\" />\n                <TextBlock\n                    x:Name=\"AppTitleBarText\"\n                    x:Uid=\"OobeWindow_TitleTxt\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource CaptionTextBlockStyle}\"\n                    TextWrapping=\"NoWrap\" />\n            </StackPanel>\n        </Grid>\n\n        <NavigationView\n            x:Name=\"navigationView\"\n            Grid.Row=\"1\"\n            DisplayModeChanged=\"NavigationView_DisplayModeChanged\"\n            IsBackButtonVisible=\"Collapsed\"\n            IsPaneOpen=\"True\"\n            IsPaneToggleButtonVisible=\"False\"\n            IsSettingsVisible=\"False\"\n            OpenPaneLength=\"296\"\n            PaneDisplayMode=\"Left\"\n            SelectionChanged=\"NavigationView_SelectionChanged\">\n            <NavigationView.MenuItems>\n                <NavigationViewItem\n                    Content=\"简介\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToys.png}\"\n                    Tag=\"Overview\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_AdvancedPaste\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/AdvancedPaste.png}\"\n                    Tag=\"AdvancedPaste\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_AlwaysOnTop\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/AlwaysOnTop.png}\"\n                    Tag=\"AlwaysOnTop\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_Awake\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/Awake.png}\"\n                    Tag=\"Awake\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_ColorPicker\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ColorPicker.png}\"\n                    Tag=\"ColorPicker\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_CmdNotFound\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/CommandNotFound.png}\"\n                    Tag=\"CmdNotFound\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_CropAndLock\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/CropAndLock.png}\"\n                    Tag=\"CropAndLock\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_EnvironmentVariables\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/EnvironmentVariables.png}\"\n                    Tag=\"EnvironmentVariables\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_FancyZones\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/FancyZones.png}\"\n                    Tag=\"FancyZones\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_FileLocksmith\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/FileLocksmith.png}\"\n                    Tag=\"FileLocksmith\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_PowerPreview\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/FileExplorerPreview.png}\"\n                    Tag=\"FileExplorer\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_Hosts\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/Hosts.png}\"\n                    Tag=\"Hosts\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_ImageResizer\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ImageResizer.png}\"\n                    Tag=\"ImageResizer\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_KeyboardManager\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/KeyboardManager.png}\"\n                    Tag=\"KBM\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_MouseUtilities\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseUtils.png}\"\n                    Tag=\"MouseUtils\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_MouseWithoutBorders\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseWithoutBorders.png}\"\n                    Tag=\"MouseWithoutBorders\" />\n                <NavigationViewItem\n                    x:Uid=\"NewPlus_Product_Name\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/NewPlus.png}\"\n                    Tag=\"NewPlus\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_Peek\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/Peek.png}\"\n                    Tag=\"Peek\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_PowerRename\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerRename.png}\"\n                    Tag=\"PowerRename\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_PowerLauncher\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToysRun.png}\"\n                    Tag=\"Run\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_QuickAccent\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/QuickAccent.png}\"\n                    Tag=\"QuickAccent\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_RegistryPreview\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/RegistryPreview.png}\"\n                    Tag=\"RegistryPreview\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_MeasureTool\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ScreenRuler.png}\"\n                    Tag=\"MeasureTool\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_ShortcutGuide\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ShortcutGuide.png}\"\n                    Tag=\"ShortcutGuide\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_TextExtractor\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/TextExtractor.png}\"\n                    Tag=\"TextExtractor\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_Workspaces\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/Workspaces.png}\"\n                    Tag=\"Workspaces\" />\n                <NavigationViewItem\n                    x:Uid=\"Shell_ZoomIt\"\n                    Icon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ZoomIt.png}\"\n                    Tag=\"ZoomIt\" />\n            </NavigationView.MenuItems>\n            <NavigationView.FooterMenuItems>\n                <NavigationViewItem\n                    x:Uid=\"Shell_WhatsNew\"\n                    Icon=\"{ui:FontIcon Glyph=&#xE789;}\"\n                    Tag=\"WhatsNew\" />\n            </NavigationView.FooterMenuItems>\n            <NavigationView.Content>\n                <Frame x:Name=\"NavigationFrame\" />\n            </NavigationView.Content>\n        </NavigationView>\n\n        <VisualStateManager.VisualStateGroups>\n            <VisualStateGroup x:Name=\"LayoutVisualStates\">\n                <VisualState x:Name=\"WideLayout\">\n                    <VisualState.StateTriggers>\n                        <AdaptiveTrigger MinWindowWidth=\"720\" />\n                    </VisualState.StateTriggers>\n                </VisualState>\n                <VisualState x:Name=\"SmallLayout\">\n                    <VisualState.StateTriggers>\n                        <AdaptiveTrigger MinWindowWidth=\"600\" />\n                        <AdaptiveTrigger MinWindowWidth=\"0\" />\n                    </VisualState.StateTriggers>\n                    <VisualState.Setters>\n                        <Setter Target=\"navigationView.PaneDisplayMode\" Value=\"LeftMinimal\" />\n                    </VisualState.Setters>\n                </VisualState>\n            </VisualStateGroup>\n        </VisualStateManager.VisualStateGroups>\n    </Grid>\n</UserControl>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/OOBE/Views/OobeShellPage.xaml.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.ObjectModel;\nusing System.Globalization;\n\nusing ManagedCommon;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Microsoft.PowerToys.Settings.UI.OOBE.Enums;\nusing Microsoft.PowerToys.Settings.UI.OOBE.ViewModel;\nusing Microsoft.UI.Xaml;\nusing Microsoft.UI.Xaml.Controls;\nusing WinRT.Interop;\n\nnamespace Microsoft.PowerToys.Settings.UI.OOBE.Views\n{\n    public sealed partial class OobeShellPage : UserControl\n    {\n        public static Func<string> RunSharedEventCallback { get; set; }\n\n        public static void SetRunSharedEventCallback(Func<string> implementation)\n        {\n            RunSharedEventCallback = implementation;\n        }\n\n        public static Func<string> ColorPickerSharedEventCallback { get; set; }\n\n        public static void SetColorPickerSharedEventCallback(Func<string> implementation)\n        {\n            ColorPickerSharedEventCallback = implementation;\n        }\n\n        public static Action<Type> OpenMainWindowCallback { get; set; }\n\n        public static void SetOpenMainWindowCallback(Action<Type> implementation)\n        {\n            OpenMainWindowCallback = implementation;\n        }\n\n        /// <summary>\n        /// Gets view model.\n        /// </summary>\n        public OobeShellViewModel ViewModel { get; } = new OobeShellViewModel();\n\n        /// <summary>\n        /// Gets or sets a shell handler to be used to update contents of the shell dynamically from page within the frame.\n        /// </summary>\n        public static OobeShellPage OobeShellHandler { get; set; }\n\n        public ObservableCollection<OobePowerToysModule> Modules { get; }\n\n        private static ISettingsUtils settingsUtils = new SettingsUtils();\n\n        // NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.\n        private bool ExperimentationToggleSwitchEnabled { get; set; } = true;\n\n        public OobeShellPage()\n        {\n            InitializeComponent();\n\n            // NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.\n            ExperimentationToggleSwitchEnabled = SettingsRepository<GeneralSettings>.GetInstance(settingsUtils).SettingsConfig.EnableExperimentation;\n            SetTitleBar();\n            DataContext = ViewModel;\n            OobeShellHandler = this;\n            Modules = new ObservableCollection<OobePowerToysModule>();\n\n            Modules.Insert((int)PowerToysModules.Overview, new OobePowerToysModule()\n            {\n                ModuleName = \"Overview\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.AdvancedPaste, new OobePowerToysModule()\n            {\n                ModuleName = \"AdvancedPaste\",\n                IsNew = true,\n            });\n            Modules.Insert((int)PowerToysModules.AlwaysOnTop, new OobePowerToysModule()\n            {\n                ModuleName = \"AlwaysOnTop\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.Awake, new OobePowerToysModule()\n            {\n                ModuleName = \"Awake\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.CmdNotFound, new OobePowerToysModule()\n            {\n                ModuleName = \"CmdNotFound\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.ColorPicker, new OobePowerToysModule()\n            {\n                ModuleName = \"ColorPicker\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.CropAndLock, new OobePowerToysModule()\n            {\n                ModuleName = \"CropAndLock\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.EnvironmentVariables, new OobePowerToysModule()\n            {\n                ModuleName = \"EnvironmentVariables\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.FancyZones, new OobePowerToysModule()\n            {\n                ModuleName = \"FancyZones\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.FileLocksmith, new OobePowerToysModule()\n            {\n                ModuleName = \"FileLocksmith\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.FileExplorer, new OobePowerToysModule()\n            {\n                ModuleName = \"FileExplorer\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.ImageResizer, new OobePowerToysModule()\n            {\n                ModuleName = \"ImageResizer\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.KBM, new OobePowerToysModule()\n            {\n                ModuleName = \"KBM\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.MouseUtils, new OobePowerToysModule()\n            {\n                ModuleName = \"MouseUtils\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.MouseWithoutBorders, new OobePowerToysModule()\n            {\n                ModuleName = \"MouseWithoutBorders\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.Peek, new OobePowerToysModule()\n            {\n                ModuleName = \"Peek\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.PowerRename, new OobePowerToysModule()\n            {\n                ModuleName = \"PowerRename\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.Run, new OobePowerToysModule()\n            {\n                ModuleName = \"Run\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.QuickAccent, new OobePowerToysModule()\n            {\n                ModuleName = \"QuickAccent\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.ShortcutGuide, new OobePowerToysModule()\n            {\n                ModuleName = \"ShortcutGuide\",\n                IsNew = false,\n            });\n            Modules.Insert((int)PowerToysModules.TextExtractor, new OobePowerToysModule()\n            {\n                ModuleName = \"TextExtractor\",\n                IsNew = false,\n            });\n\n            Modules.Insert((int)PowerToysModules.MeasureTool, new OobePowerToysModule()\n            {\n                ModuleName = \"MeasureTool\",\n                IsNew = false,\n            });\n\n            Modules.Insert((int)PowerToysModules.Hosts, new OobePowerToysModule()\n            {\n                ModuleName = \"Hosts\",\n                IsNew = false,\n            });\n\n            Modules.Insert((int)PowerToysModules.Workspaces, new OobePowerToysModule()\n            {\n                ModuleName = \"Workspaces\",\n                IsNew = true,\n            });\n\n            Modules.Insert((int)PowerToysModules.WhatsNew, new OobePowerToysModule()\n            {\n                ModuleName = \"WhatsNew\",\n                IsNew = false,\n            });\n\n            Modules.Insert((int)PowerToysModules.RegistryPreview, new OobePowerToysModule()\n            {\n                ModuleName = \"RegistryPreview\",\n                IsNew = false,\n            });\n\n            Modules.Insert((int)PowerToysModules.NewPlus, new OobePowerToysModule()\n            {\n                ModuleName = \"NewPlus\",\n                IsNew = true,\n            });\n\n            Modules.Insert((int)PowerToysModules.ZoomIt, new OobePowerToysModule()\n            {\n                ModuleName = \"ZoomIt\",\n                IsNew = true,\n            });\n        }\n\n        public void OnClosing()\n        {\n            Microsoft.UI.Xaml.Controls.NavigationViewItem selectedItem = this.navigationView.SelectedItem as Microsoft.UI.Xaml.Controls.NavigationViewItem;\n            if (selectedItem != null)\n            {\n                Modules[(int)(PowerToysModules)Enum.Parse(typeof(PowerToysModules), (string)selectedItem.Tag, true)].LogClosingModuleEvent();\n            }\n        }\n\n        public void NavigateToModule(PowerToysModules selectedModule)\n        {\n            if (selectedModule == PowerToysModules.WhatsNew)\n            {\n                navigationView.SelectedItem = navigationView.FooterMenuItems[0];\n            }\n            else\n            {\n                navigationView.SelectedItem = navigationView.MenuItems[(int)selectedModule];\n            }\n        }\n\n        private void NavigationView_SelectionChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewSelectionChangedEventArgs args)\n        {\n            Microsoft.UI.Xaml.Controls.NavigationViewItem selectedItem = args.SelectedItem as Microsoft.UI.Xaml.Controls.NavigationViewItem;\n\n            if (selectedItem != null)\n            {\n                switch (selectedItem.Tag)\n                {\n                    case \"Overview\": // NavigationFrame.Navigate(typeof(OobeOverview)); break;\n                    // NOTE: Experimentation for OOBE is currently turned off on server side. Keeping this code in a comment to allow future experiments.\n                        if (ExperimentationToggleSwitchEnabled && global::PowerToys.GPOWrapper.GPOWrapper.GetAllowExperimentationValue() != global::PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)\n                        {\n                            /*switch (AllExperiments.Experiments.LandingPageExperiment)\n                            {\n                                case Experiments.ExperimentState.Enabled:\n                                    NavigationFrame.Navigate(typeof(OobeOverviewAlternate)); break;\n                                case Experiments.ExperimentState.Disabled:\n                                    NavigationFrame.Navigate(typeof(OobeOverview)); break;\n                                case Experiments.ExperimentState.NotLoaded:\n                                    NavigationFrame.Navigate(typeof(OobeOverviewPlaceholder)); break;\n                            }*/\n                            // NOW IT'S YOUR FREEDOM TO ENABLE IT ;)\n                            NavigationFrame.Navigate(typeof(OobeOverviewAlternate));\n\n                            break;\n                        }\n                        else\n                        {\n                            NavigationFrame.Navigate(typeof(OobeOverview));\n                            break;\n                        }\n\n                    case \"WhatsNew\": NavigationFrame.Navigate(typeof(OobeWhatsNew)); break;\n                    case \"AdvancedPaste\": NavigationFrame.Navigate(typeof(OobeAdvancedPaste)); break;\n                    case \"AlwaysOnTop\": NavigationFrame.Navigate(typeof(OobeAlwaysOnTop)); break;\n                    case \"Awake\": NavigationFrame.Navigate(typeof(OobeAwake)); break;\n                    case \"CmdNotFound\": NavigationFrame.Navigate(typeof(OobeCmdNotFound)); break;\n                    case \"ColorPicker\": NavigationFrame.Navigate(typeof(OobeColorPicker)); break;\n                    case \"CropAndLock\": NavigationFrame.Navigate(typeof(OobeCropAndLock)); break;\n                    case \"EnvironmentVariables\": NavigationFrame.Navigate(typeof(OobeEnvironmentVariables)); break;\n                    case \"FancyZones\": NavigationFrame.Navigate(typeof(OobeFancyZones)); break;\n                    case \"FileLocksmith\": NavigationFrame.Navigate(typeof(OobeFileLocksmith)); break;\n                    case \"Run\": NavigationFrame.Navigate(typeof(OobeRun)); break;\n                    case \"ImageResizer\": NavigationFrame.Navigate(typeof(OobeImageResizer)); break;\n                    case \"KBM\": NavigationFrame.Navigate(typeof(OobeKBM)); break;\n                    case \"PowerRename\": NavigationFrame.Navigate(typeof(OobePowerRename)); break;\n                    case \"QuickAccent\": NavigationFrame.Navigate(typeof(OobePowerAccent)); break;\n                    case \"FileExplorer\": NavigationFrame.Navigate(typeof(OobeFileExplorer)); break;\n                    case \"ShortcutGuide\": NavigationFrame.Navigate(typeof(OobeShortcutGuide)); break;\n                    case \"TextExtractor\": NavigationFrame.Navigate(typeof(OobePowerOCR)); break;\n                    case \"MouseUtils\": NavigationFrame.Navigate(typeof(OobeMouseUtils)); break;\n                    case \"MouseWithoutBorders\": NavigationFrame.Navigate(typeof(OobeMouseWithoutBorders)); break;\n                    case \"MeasureTool\": NavigationFrame.Navigate(typeof(OobeMeasureTool)); break;\n                    case \"Hosts\": NavigationFrame.Navigate(typeof(OobeHosts)); break;\n                    case \"RegistryPreview\": NavigationFrame.Navigate(typeof(OobeRegistryPreview)); break;\n                    case \"Peek\": NavigationFrame.Navigate(typeof(OobePeek)); break;\n                    case \"NewPlus\": NavigationFrame.Navigate(typeof(OobeNewPlus)); break;\n                    case \"Workspaces\": NavigationFrame.Navigate(typeof(OobeWorkspaces)); break;\n                    case \"ZoomIt\": NavigationFrame.Navigate(typeof(OobeZoomIt)); break;\n                }\n            }\n        }\n\n        private void SetTitleBar()\n        {\n            var u = App.GetOobeWindow();\n            if (u != null)\n            {\n                // A custom title bar is required for full window theme and Mica support.\n                // https://docs.microsoft.com/windows/apps/develop/title-bar?tabs=winui3#full-customization\n                u.ExtendsContentIntoTitleBar = true;\n                WindowHelpers.ForceTopBorder1PixelInsetOnWindows10(WindowNative.GetWindowHandle(u));\n                u.SetTitleBar(AppTitleBar);\n            }\n        }\n\n        private void ShellPage_Loaded(object sender, RoutedEventArgs e)\n        {\n            SetTitleBar();\n        }\n\n        private void NavigationView_DisplayModeChanged(NavigationView sender, NavigationViewDisplayModeChangedEventArgs args)\n        {\n            if (args.DisplayMode == NavigationViewDisplayMode.Compact || args.DisplayMode == NavigationViewDisplayMode.Minimal)\n            {\n                PaneToggleBtn.Visibility = Visibility.Visible;\n                AppTitleBar.Margin = new Thickness(48, 0, 0, 0);\n                AppTitleBarText.Margin = new Thickness(12, 0, 0, 0);\n            }\n            else\n            {\n                PaneToggleBtn.Visibility = Visibility.Collapsed;\n                AppTitleBar.Margin = new Thickness(16, 0, 0, 0);\n                AppTitleBarText.Margin = new Thickness(16, 0, 0, 0);\n            }\n        }\n\n        private void PaneToggleBtn_Click(object sender, RoutedEventArgs e)\n        {\n            navigationView.IsPaneOpen = !navigationView.IsPaneOpen;\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/ColorPickerPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.ColorPickerPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:models=\"using:Microsoft.PowerToys.Settings.UI.Library\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:tkconverters=\"using:CommunityToolkit.WinUI.Converters\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    xmlns:viewmodels=\"using:Microsoft.PowerToys.Settings.UI.ViewModels\"\n    x:Name=\"RootPage\"\n    d:DataContext=\"{d:DesignInstance Type=viewmodels:ColorPickerViewModel}\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n\n    <Page.Resources>\n        <tkconverters:BoolToVisibilityConverter x:Key=\"BoolToVis\" />\n    </Page.Resources>\n\n    <controls:SettingsPageControl x:Uid=\"ColorPicker\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/ColorPicker.png\">\n        <controls:SettingsPageControl.ModuleContent>\n\n            <StackPanel\n                x:Name=\"ColorPickerView\"\n                ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\"\n                Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    x:Uid=\"ColorPicker_EnableColorPicker\"\n                    HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ColorPicker.png}\"\n                    IsEnabled=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                    <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsEnabled, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <InfoBar\n                    x:Uid=\"GPO_SettingIsManaged\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    Severity=\"Informational\">\n                    <InfoBar.IconSource>\n                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                    </InfoBar.IconSource>\n                </InfoBar>\n\n                <controls:SettingsGroup x:Uid=\"Shortcut\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"Activation_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"ColorPicker_ActivationAction\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEC4E;}\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind Path=ViewModel.ActivationBehavior, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"EditorFirst\" />\n                            <ComboBoxItem x:Uid=\"ColorPickerFirst\" />\n                            <ComboBoxItem x:Uid=\"ColorPickerOnly\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"ColorFormats\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ColorPicker_CopiedColorRepresentation\" HeaderIcon=\"{ui:FontIcon Glyph=&#xF0E3;}\">\n                        <ComboBox\n                            x:Name=\"ColorPicker_ComboBox\"\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            DisplayMemberPath=\"Value\"\n                            ItemsSource=\"{Binding ColorFormatsPreview, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                            Loaded=\"ColorPicker_ComboBox_Loaded\"\n                            SelectedIndex=\"{Binding ColorFormatsPreviewIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                            SelectedValue=\"{Binding SelectedColorRepresentationValue, Mode=TwoWay}\"\n                            SelectedValuePath=\"Key\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"ColorPicker_ShowColorName\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{Binding ShowColorName, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <!--\n                Disabling this until we have a safer way to reset cursor as\n                we can hit a state where the cursor doesn't reset\n\n                <CheckBox x:Uid=\"ColorPicker_ChangeCursor\"\n                        IsChecked=\"{Binding ChangeCursor, Mode=TwoWay}\"\n                        Margin=\"{StaticResource SmallTopMargin}\"\n                        IsEnabled=\"{Binding IsEnabled}\"/>\n                    -->\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"ColorPicker_Editor\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard\n                        x:Name=\"ColorFormatsSetting\"\n                        x:Uid=\"ColorPicker_ColorFormats\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE762;}\">\n                        <Button\n                            x:Uid=\"ColorPickerAddNewFormat\"\n                            HorizontalAlignment=\"Right\"\n                            Click=\"NewFormatClick\"\n                            Style=\"{StaticResource AccentButtonStyle}\" />\n                    </tkcontrols:SettingsCard>\n                    <!--  Disabled reordering by dragging  -->\n                    <!--  CanReorderItems=\"True\" AllowDrop=\"True\"  -->\n                    <ItemsControl\n                        x:Name=\"ColorFormats\"\n                        HorizontalAlignment=\"Stretch\"\n                        AutomationProperties.Name=\"{Binding ElementName=ColorFormatsSetting, Path=Header}\"\n                        IsTabStop=\"False\"\n                        ItemsSource=\"{Binding ColorFormats, Mode=TwoWay}\">\n                        <ItemsControl.ItemTemplate>\n                            <DataTemplate x:DataType=\"models:ColorFormatModel\">\n                                <tkcontrols:SettingsCard\n                                    Margin=\"0,0,0,2\"\n                                    Click=\"EditButton_Click\"\n                                    Description=\"{x:Bind Example, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                                    Header=\"{x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                                    IsActionIconVisible=\"False\"\n                                    IsClickEnabled=\"True\">\n                                    <tkcontrols:SettingsCard.Resources>\n                                        <x:Double x:Key=\"SettingsCardLeftIndention\">42</x:Double>\n                                        <x:Double x:Key=\"SettingsCardActionButtonWidth\">0</x:Double>\n                                    </tkcontrols:SettingsCard.Resources>\n                                    <StackPanel Orientation=\"Horizontal\" Spacing=\"4\">\n                                        <ToggleSwitch\n                                            x:Uid=\"Enable_ColorFormat\"\n                                            AutomationProperties.HelpText=\"{x:Bind Name}\"\n                                            IsOn=\"{x:Bind IsShown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                                            OffContent=\"\"\n                                            OnContent=\"\" />\n\n                                        <Button\n                                            x:Uid=\"More_Options_Button\"\n                                            Grid.Column=\"1\"\n                                            VerticalAlignment=\"Center\"\n                                            Content=\"&#xE712;\"\n                                            FontFamily=\"{ThemeResource SymbolThemeFontFamily}\"\n                                            Style=\"{StaticResource SubtleButtonStyle}\">\n                                            <Button.Flyout>\n                                                <MenuFlyout>\n                                                    <MenuFlyoutItem\n                                                        x:Uid=\"MoveUp\"\n                                                        Click=\"ReorderButtonUp_Click\"\n                                                        Icon=\"{ui:FontIcon Glyph=&#xE74A;}\"\n                                                        IsEnabled=\"{x:Bind CanMoveUp, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" />\n                                                    <MenuFlyoutItem\n                                                        x:Uid=\"MoveDown\"\n                                                        Click=\"ReorderButtonDown_Click\"\n                                                        Icon=\"{ui:FontIcon Glyph=&#xE74B;}\"\n                                                        IsEnabled=\"{x:Bind CanMoveDown, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" />\n                                                    <MenuFlyoutSeparator />\n                                                    <MenuFlyoutItem\n                                                        x:Uid=\"RemoveItem\"\n                                                        Click=\"RemoveButton_Click\"\n                                                        Icon=\"{ui:FontIcon Glyph=&#xE74D;}\"\n                                                        IsEnabled=\"{x:Bind CanBeDeleted, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" />\n                                                </MenuFlyout>\n                                            </Button.Flyout>\n                                            <ToolTipService.ToolTip>\n                                                <TextBlock x:Uid=\"More_Options_ButtonTooltip\" />\n                                            </ToolTipService.ToolTip>\n                                        </Button>\n                                    </StackPanel>\n                                </tkcontrols:SettingsCard>\n                            </DataTemplate>\n                        </ItemsControl.ItemTemplate>\n                    </ItemsControl>\n                </controls:SettingsGroup>\n                <ContentDialog\n                    x:Name=\"ColorFormatDialog\"\n                    x:Uid=\"ColorFormatDialog\"\n                    Closed=\"ColorFormatDialog_Closed\"\n                    IsPrimaryButtonEnabled=\"{Binding IsValid, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                    PrimaryButtonStyle=\"{ThemeResource AccentButtonStyle}\">\n                    <ContentDialog.DataContext>\n                        <models:ColorFormatModel />\n                    </ContentDialog.DataContext>\n                    <ScrollViewer HorizontalScrollBarVisibility=\"Auto\" HorizontalScrollMode=\"Auto\">\n                        <controls:ColorFormatEditor\n                            Width=\"480\"\n                            Margin=\"2,0,0,0\"\n                            HorizontalAlignment=\"Left\"\n                            PropertyChanged=\"ColorFormatEditor_PropertyChanged\" />\n                    </ScrollViewer>\n                </ContentDialog>\n            </StackPanel>\n        </controls:SettingsPageControl.ModuleContent>\n\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_ColorPicker\" Link=\"https://aka.ms/PowerToysOverview_ColorPicker\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://github.com/martinchrzan/ColorPicker/\" Text=\"Martin Chrzan 的软件 Color Picker\" />\n            <controls:PageLink Link=\"https://medium.com/@Niels9001/a-fluent-color-meter-for-powertoys-20407ededf0c\" Text=\"Niels Laute 的界面设计\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/ImageResizerPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.ImageResizerPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:converters=\"using:Microsoft.PowerToys.Settings.UI.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:models=\"using:Microsoft.PowerToys.Settings.UI.Library\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:toolkitconverters=\"using:CommunityToolkit.WinUI.UI.Converters\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    x:Name=\"RootPage\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n    <Page.Resources>\n        <converters:ImageResizerFitToStringConverter x:Key=\"ImageResizerFitToStringConverter\" />\n        <converters:ImageResizerFitToIntConverter x:Key=\"ImageResizerFitToIntConverter\" />\n        <converters:ImageResizerUnitToStringConverter x:Key=\"ImageResizerUnitToStringConverter\" />\n        <converters:ImageResizerUnitToIntConverter x:Key=\"ImageResizerUnitToIntConverter\" />\n        <converters:ImageResizerSizeToAccessibleTextConverter x:Key=\"ImageResizerSizeToAccessibleTextConverter\" />\n        <toolkitconverters:BoolToObjectConverter\n            x:Key=\"BoolToComboBoxIndexConverter\"\n            FalseValue=\"1\"\n            TrueValue=\"0\" />\n    </Page.Resources>\n    <controls:SettingsPageControl x:Uid=\"ImageResizer\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/ImageResizer.png\">\n        <controls:SettingsPageControl.ModuleContent>\n            <StackPanel ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\">\n                <tkcontrols:SettingsCard\n                    x:Uid=\"ImageResizer_EnableToggle\"\n                    HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ImageResizer.png}\"\n                    IsEnabled=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                    <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsEnabled, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n\n                <InfoBar\n                    x:Uid=\"GPO_SettingIsManaged\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    Severity=\"Informational\">\n                    <InfoBar.IconSource>\n                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                    </InfoBar.IconSource>\n                </InfoBar>\n\n                <controls:SettingsGroup x:Uid=\"ImageResizer_CustomSizes\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ImageResizer_Presets\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE792;}\">\n                        <Button\n                            x:Uid=\"ImageResizer_AddSizeButton\"\n                            Click=\"AddSizeButton_Click\"\n                            Style=\"{ThemeResource AccentButtonStyle}\" />\n                    </tkcontrols:SettingsCard>\n                    <ListView\n                        x:Name=\"ImagesSizesListView\"\n                        x:Uid=\"ImagesSizesListView\"\n                        ContainerContentChanging=\"ImagesSizesListView_ContainerContentChanging\"\n                        ItemsSource=\"{x:Bind ViewModel.Sizes, Mode=TwoWay}\"\n                        SelectionMode=\"None\">\n                        <ListView.ItemTemplate>\n                            <DataTemplate x:Name=\"SingleLineDataTemplate\" x:DataType=\"models:ImageSize\">\n                                <tkcontrols:SettingsCard Header=\"{x:Bind Name, Mode=OneWay}\">\n                                    <tkcontrols:SettingsCard.Resources>\n                                        <x:Double x:Key=\"SettingsCardLeftIndention\">42</x:Double>\n                                    </tkcontrols:SettingsCard.Resources>\n                                    <tkcontrols:SettingsCard.Description>\n                                        <StackPanel\n                                            Grid.Row=\"1\"\n                                            Grid.Column=\"1\"\n                                            Margin=\"0,4,0,0\"\n                                            Orientation=\"Horizontal\">\n                                            <TextBlock\n                                                Margin=\"0,0,4,0\"\n                                                Style=\"{ThemeResource SecondaryTextStyle}\"\n                                                Text=\"{x:Bind Fit, Mode=OneWay, Converter={StaticResource ImageResizerFitToStringConverter}}\" />\n                                            <TextBlock\n                                                Margin=\"0,0,4,0\"\n                                                FontWeight=\"SemiBold\"\n                                                Style=\"{ThemeResource SecondaryTextStyle}\"\n                                                Text=\"{x:Bind Width, Mode=OneWay}\" />\n                                            <TextBlock\n                                                Margin=\"0,5,4,0\"\n                                                AutomationProperties.AccessibilityView=\"Raw\"\n                                                FontFamily=\"{ThemeResource SymbolThemeFontFamily}\"\n                                                FontSize=\"10\"\n                                                Style=\"{ThemeResource SecondaryTextStyle}\"\n                                                Text=\"&#xE947;\"\n                                                Visibility=\"{x:Bind IsHeightUsed, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\" />\n                                            <TextBlock\n                                                Margin=\"0,0,4,0\"\n                                                FontWeight=\"SemiBold\"\n                                                Style=\"{ThemeResource SecondaryTextStyle}\"\n                                                Text=\"{x:Bind Height, Mode=OneWay}\"\n                                                Visibility=\"{x:Bind IsHeightUsed, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\" />\n                                            <TextBlock\n                                                Margin=\"0,0,4,0\"\n                                                Style=\"{ThemeResource SecondaryTextStyle}\"\n                                                Text=\"{x:Bind Unit, Mode=OneWay, Converter={StaticResource ImageResizerUnitToStringConverter}, ConverterParameter=ToLower}\" />\n                                        </StackPanel>\n                                    </tkcontrols:SettingsCard.Description>\n                                    <StackPanel\n                                        Grid.Column=\"2\"\n                                        HorizontalAlignment=\"Right\"\n                                        Orientation=\"Horizontal\"\n                                        Spacing=\"8\">\n                                        <Button\n                                            x:Uid=\"ImageResizer_EditButton\"\n                                            Width=\"40\"\n                                            Height=\"36\"\n                                            AutomationProperties.FullDescription=\"{x:Bind AccessibleTextHelper, Mode=OneWay, Converter={StaticResource ImageResizerSizeToAccessibleTextConverter}, ConverterParameter='Edit'}\"\n                                            AutomationProperties.Name=\"{x:Bind Name, Mode=OneWay, Converter={StaticResource ImageResizerSizeToAccessibleTextConverter}, ConverterParameter='Edit'}\"\n                                            Content=\"&#xE70F;\"\n                                            FontFamily=\"{ThemeResource SymbolThemeFontFamily}\"\n                                            Style=\"{StaticResource SubtleButtonStyle}\">\n                                            <ToolTipService.ToolTip>\n                                                <TextBlock x:Uid=\"EditTooltip\" />\n                                            </ToolTipService.ToolTip>\n                                            <Button.Flyout>\n                                                <Flyout x:Uid=\"ImageResizer_EditSize\" ShouldConstrainToRootBounds=\"False\">\n                                                    <StackPanel Spacing=\"16\">\n                                                        <TextBox\n                                                            x:Uid=\"ImageResizer_Name\"\n                                                            Width=\"240\"\n                                                            HorizontalAlignment=\"Left\"\n                                                            Text=\"{x:Bind Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" />\n\n                                                        <ComboBox\n                                                            x:Uid=\"ImageResizer_Fit\"\n                                                            Width=\"240\"\n                                                            HorizontalAlignment=\"Left\"\n                                                            SelectedIndex=\"{x:Bind Fit, Mode=TwoWay, Converter={StaticResource ImageResizerFitToIntConverter}}\">\n                                                            <ComboBoxItem x:Uid=\"ImageResizer_Sizes_Fit_Fill\" />\n                                                            <ComboBoxItem x:Uid=\"ImageResizer_Sizes_Fit_Fit\" />\n                                                            <ComboBoxItem x:Uid=\"ImageResizer_Sizes_Fit_Stretch\" />\n                                                        </ComboBox>\n\n                                                        <StackPanel Orientation=\"Horizontal\" Spacing=\"8\">\n                                                            <NumberBox\n                                                                x:Uid=\"ImageResizer_Width\"\n                                                                Width=\"116\"\n                                                                Minimum=\"0\"\n                                                                SpinButtonPlacementMode=\"Compact\"\n                                                                Value=\"{x:Bind Width, Mode=TwoWay}\" />\n\n                                                            <NumberBox\n                                                                x:Uid=\"ImageResizer_Height\"\n                                                                Width=\"116\"\n                                                                Minimum=\"0\"\n                                                                SpinButtonPlacementMode=\"Compact\"\n                                                                Visibility=\"{x:Bind IsHeightUsed, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\"\n                                                                Value=\"{x:Bind Height, Mode=TwoWay}\" />\n                                                        </StackPanel>\n\n                                                        <ComboBox\n                                                            x:Uid=\"ImageResizer_Size\"\n                                                            Width=\"240\"\n                                                            SelectedIndex=\"{Binding Unit, Mode=TwoWay, Converter={StaticResource ImageResizerUnitToIntConverter}}\">\n                                                            <ComboBoxItem x:Uid=\"ImageResizer_Sizes_Units_CM\" />\n                                                            <ComboBoxItem x:Uid=\"ImageResizer_Sizes_Units_Inches\" />\n                                                            <ComboBoxItem x:Uid=\"ImageResizer_Sizes_Units_Percent\" />\n                                                            <ComboBoxItem x:Uid=\"ImageResizer_Sizes_Units_Pixels\" />\n                                                        </ComboBox>\n                                                    </StackPanel>\n                                                </Flyout>\n                                            </Button.Flyout>\n                                        </Button>\n\n                                        <Button\n                                            x:Uid=\"ImageResizer_RemoveButton\"\n                                            Width=\"40\"\n                                            Height=\"36\"\n                                            AutomationProperties.FullDescription=\"{x:Bind AccessibleTextHelper, Mode=OneWay, Converter={StaticResource ImageResizerSizeToAccessibleTextConverter}, ConverterParameter='Remove'}\"\n                                            AutomationProperties.Name=\"{x:Bind Name, Mode=OneWay, Converter={StaticResource ImageResizerSizeToAccessibleTextConverter}, ConverterParameter='Remove'}\"\n                                            Click=\"DeleteCustomSize\"\n                                            CommandParameter=\"{Binding Id}\"\n                                            Content=\"&#xE74D;\"\n                                            FontFamily=\"{ThemeResource SymbolThemeFontFamily}\"\n                                            Style=\"{StaticResource SubtleButtonStyle}\">\n                                            <ToolTipService.ToolTip>\n                                                <TextBlock x:Uid=\"RemoveTooltip\" />\n                                            </ToolTipService.ToolTip>\n                                        </Button>\n                                    </StackPanel>\n                                </tkcontrols:SettingsCard>\n                            </DataTemplate>\n                        </ListView.ItemTemplate>\n                    </ListView>\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"Encoding\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ImageResizer_FallBackEncoderText\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.Encoder, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"ImageResizer_FallbackEncoder_PNG\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_FallbackEncoder_BMP\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_FallbackEncoder_JPEG\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_FallbackEncoder_TIFF\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_FallbackEncoder_WMPhoto\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_FallbackEncoder_GIF\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"ImageResizer_Encoding\">\n                        <Slider\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            Maximum=\"100\"\n                            Minimum=\"0\"\n                            Value=\"{x:Bind ViewModel.JPEGQualityLevel, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"ImageResizer_PNGInterlacing\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.PngInterlaceOption, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"Default\" />\n                            <ComboBoxItem x:Uid=\"On\" />\n                            <ComboBoxItem x:Uid=\"Off\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"ImageResizer_TIFFCompression\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.TiffCompressOption, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"ImageResizer_ENCODER_TIFF_Default\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_ENCODER_TIFF_None\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_ENCODER_TIFF_CCITT3\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_ENCODER_TIFF_CCITT4\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_ENCODER_TIFF_LZW\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_ENCODER_TIFF_RLE\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_ENCODER_TIFF_Zip\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"File\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ImageResizer_FilenameFormatHeader\">\n                        <StackPanel Orientation=\"Horizontal\" Spacing=\"4\">\n                            <TextBox\n                                x:Uid=\"ImageResizer_FilenameFormatPlaceholder\"\n                                MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                Text=\"{x:Bind ViewModel.FileName, Mode=TwoWay}\" />\n                            <Button\n                                x:Uid=\"ImageResizer_FilenameParameters\"\n                                Content=\"&#xE946;\"\n                                FontFamily=\"{ThemeResource SymbolThemeFontFamily}\"\n                                Style=\"{StaticResource SubtleButtonStyle}\">\n                                <Button.Flyout>\n                                    <Flyout ShouldConstrainToRootBounds=\"False\">\n                                        <TextBlock x:Name=\"FileFormatTextBlock\">\n                                            <Run x:Uid=\"ImageResizer_FileFormatDescription\" />\n                                            <LineBreak />\n                                            <LineBreak />\n                                            <Run FontWeight=\"Bold\" Text=\"%1\" />\n                                            <Run Text=\" - \" />\n                                            <Run x:Uid=\"ImageResizer_Formatting_Filename\" />\n                                            <LineBreak />\n                                            <Run FontWeight=\"Bold\" Text=\"%2\" />\n                                            <Run Text=\" - \" />\n                                            <Run x:Uid=\"ImageResizer_Formatting_Sizename\" />\n                                            <LineBreak />\n                                            <Run FontWeight=\"Bold\" Text=\"%3\" />\n                                            <Run Text=\" - \" />\n                                            <Run x:Uid=\"ImageResizer_Formatting_SelectedWidth\" />\n                                            <LineBreak />\n                                            <Run FontWeight=\"Bold\" Text=\"%4\" />\n                                            <Run Text=\" - \" />\n                                            <Run x:Uid=\"ImageResizer_Formatting_SelectedHeight\" />\n                                            <LineBreak />\n                                            <Run FontWeight=\"Bold\" Text=\"%5\" />\n                                            <Run Text=\" - \" />\n                                            <Run x:Uid=\"ImageResizer_Formatting_ActualWidth\" />\n                                            <LineBreak />\n                                            <Run FontWeight=\"Bold\" Text=\"%6\" />\n                                            <Run Text=\" - \" />\n                                            <Run x:Uid=\"ImageResizer_Formatting_ActualHeight\" />\n                                        </TextBlock>\n                                    </Flyout>\n                                </Button.Flyout>\n                            </Button>\n                        </StackPanel>\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"ImageResizer_FileModifiedDate\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.KeepDateModified, Mode=TwoWay, Converter={StaticResource ReverseBoolToComboBoxIndexConverter}}\">\n                            <ComboBoxItem x:Uid=\"ImageResizer_UseOriginalDate\" />\n                            <ComboBoxItem x:Uid=\"ImageResizer_UseResizeDate\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n            </StackPanel>\n\n        </controls:SettingsPageControl.ModuleContent>\n\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_ImageResizer\" Link=\"https://aka.ms/PowerToysOverview_ImageResizer\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://github.com/bricelam/ImageResizer/\" Text=\"Brice Lambson 的软件 ImageResizer\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseUtilsPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.MouseUtilsPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:converters=\"using:Microsoft.PowerToys.Settings.UI.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:panels=\"using:Microsoft.PowerToys.Settings.UI.Panels\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:tkconverters=\"using:CommunityToolkit.WinUI.Converters\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n    <Page.Resources>\n        <converters:IndexBitFieldToVisibilityConverter x:Key=\"IndexBitFieldToVisibilityConverter\" />\n        <tkconverters:BoolToVisibilityConverter\n            x:Key=\"BoolToInvertedVisibilityConverter\"\n            FalseValue=\"Visible\"\n            TrueValue=\"Collapsed\" />\n    </Page.Resources>\n    <controls:SettingsPageControl x:Uid=\"MouseUtils\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/MouseUtils.png\">\n        <controls:SettingsPageControl.ModuleContent>\n            <StackPanel ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\" Orientation=\"Vertical\">\n                <controls:SettingsGroup x:Uid=\"MouseUtils_FindMyMouse\">\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"MouseUtils_Enable_FindMyMouse\"\n                        HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/FindMyMouse.png}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsFindMyMouseEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <InfoBar\n                        x:Uid=\"GPO_SettingIsManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.IsFindMyMouseEnabledGpoConfigured, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.IsFindMyMouseEnabledGpoConfigured, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"MouseUtils_FindMyMouse_ActivationMethod\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE961;}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=OneWay}\"\n                        IsExpanded=\"True\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind Path=ViewModel.FindMyMouseActivationMethod, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"MouseUtils_FindMyMouse_ActivationDoubleControlPress\" />\n                            <ComboBoxItem x:Uid=\"MouseUtils_FindMyMouse_ActivationDoubleRightControlPress\" />\n                            <ComboBoxItem x:Uid=\"MouseUtils_FindMyMouse_ActivationShakeMouse\" />\n                            <ComboBoxItem x:Uid=\"MouseUtils_FindMyMouse_ActivationCustomizedShortcut\" />\n                        </ComboBox>\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\" Visibility=\"{x:Bind ViewModel.FindMyMouseActivationMethod, Converter={StaticResource IndexBitFieldToVisibilityConverter}, Mode=OneWay, ConverterParameter=0x3}\">\n                                <!--  Visible for both Press Left Control twice and Press Right Control twice activation methods  -->\n                                <CheckBox x:Uid=\"MouseUtils_Include_Win_Key\" IsChecked=\"{x:Bind ViewModel.FindMyMouseIncludeWinKey, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_ShakingMinimumDistance\" Visibility=\"{x:Bind ViewModel.FindMyMouseActivationMethod, Converter={StaticResource IndexBitFieldToVisibilityConverter}, Mode=OneWay, ConverterParameter=0x4}\">\n                                <!--  Visible for the Shake Mouse activation method  -->\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"1000\"\n                                    Maximum=\"1000000\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"100\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.FindMyMouseShakingMinimumDistance, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_ShakingIntervalMs\" Visibility=\"{x:Bind ViewModel.FindMyMouseActivationMethod, Converter={StaticResource IndexBitFieldToVisibilityConverter}, Mode=OneWay, ConverterParameter=0x4}\">\n                                <!--  Visible for the Shake Mouse activation method  -->\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"1000\"\n                                    Maximum=\"10000\"\n                                    Minimum=\"100\"\n                                    SmallChange=\"100\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.FindMyMouseShakingIntervalMs, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_ShakingFactor\" Visibility=\"{x:Bind ViewModel.FindMyMouseActivationMethod, Converter={StaticResource IndexBitFieldToVisibilityConverter}, Mode=OneWay, ConverterParameter=0x4}\">\n                                <!--  Visible for the Shake Mouse activation method  -->\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"100\"\n                                    Maximum=\"10000\"\n                                    Minimum=\"150\"\n                                    SmallChange=\"10\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.FindMyMouseShakingFactor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard\n                                x:Uid=\"MouseUtils_FindMyMouse_ActivationShortcut\"\n                                HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\"\n                                Visibility=\"{x:Bind ViewModel.FindMyMouseActivationMethod, Converter={StaticResource IndexBitFieldToVisibilityConverter}, Mode=OneWay, ConverterParameter=0x8}\">\n                                <!--  Visible for the Shortcut activation method  -->\n                                <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.FindMyMouseActivationShortcut, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <CheckBox x:Uid=\"MouseUtils_Prevent_Activation_On_Game_Mode\" IsChecked=\"{x:Bind ViewModel.FindMyMouseDoNotActivateOnGameMode, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"Appearance_Behavior\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEB3C;}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=OneWay}\"\n                        IsExpanded=\"False\">\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_OverlayOpacity\">\n                                <Slider\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    Maximum=\"100\"\n                                    Minimum=\"1\"\n                                    Value=\"{x:Bind ViewModel.FindMyMouseOverlayOpacity, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_BackgroundColor\">\n                                <controls:ColorPickerButton SelectedColor=\"{x:Bind Path=ViewModel.FindMyMouseBackgroundColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_SpotlightColor\">\n                                <controls:ColorPickerButton SelectedColor=\"{x:Bind Path=ViewModel.FindMyMouseSpotlightColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_SpotlightRadius\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"10\"\n                                    Minimum=\"5\"\n                                    SmallChange=\"1\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.FindMyMouseSpotlightRadius, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_SpotlightInitialZoom\">\n                                <Slider\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    Maximum=\"40\"\n                                    Minimum=\"1\"\n                                    Value=\"{x:Bind ViewModel.FindMyMouseSpotlightInitialZoom, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_FindMyMouse_AnimationDurationMs\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    IsEnabled=\"{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay}\"\n                                    LargeChange=\"100\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"10\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.FindMyMouseAnimationDurationMs, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                    <InfoBar\n                        x:Uid=\"MouseUtils_FindMyMouse_AnimationDurationMs_Disabled\"\n                        IsClosable=\"False\"\n                        IsOpen=\"True\"\n                        Severity=\"Informational\"\n                        Visibility=\"{x:Bind ViewModel.IsAnimationEnabledBySystem, Mode=OneWay, Converter={StaticResource BoolToInvertedVisibilityConverter}}\">\n                        <InfoBar.ActionButton>\n                            <HyperlinkButton x:Uid=\"OpenSettings\" Click=\"OpenAnimationsSettings_Click\" />\n                        </InfoBar.ActionButton>\n                    </InfoBar>\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"MouseUtils_FindMyMouse_ExcludedApps\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xECE4;}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=OneWay}\">\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard HorizontalContentAlignment=\"Stretch\" ContentAlignment=\"Vertical\">\n                                <TextBox\n                                    x:Uid=\"MouseUtils_FindMyMouse_ExcludedApps_TextBoxControl\"\n                                    MinWidth=\"240\"\n                                    MinHeight=\"160\"\n                                    AcceptsReturn=\"True\"\n                                    IsEnabled=\"{x:Bind ViewModel.IsFindMyMouseEnabled, Mode=OneWay}\"\n                                    ScrollViewer.IsVerticalRailEnabled=\"True\"\n                                    ScrollViewer.VerticalScrollBarVisibility=\"Visible\"\n                                    ScrollViewer.VerticalScrollMode=\"Enabled\"\n                                    Text=\"{x:Bind ViewModel.FindMyMouseExcludedApps, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                                    TextWrapping=\"Wrap\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"MouseUtils_MouseHighlighter\">\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"MouseUtils_Enable_MouseHighlighter\"\n                        HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseHighlighter.png}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsHighlighterEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsMouseHighlighterEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <InfoBar\n                        x:Uid=\"GPO_SettingIsManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.IsHighlighterEnabledGpoConfigured, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.IsHighlighterEnabledGpoConfigured, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"MouseUtils_MouseHighlighter_ActivationShortcut\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsMouseHighlighterEnabled, Mode=OneWay}\"\n                        IsExpanded=\"True\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.MouseHighlighterActivationShortcut, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <CheckBox x:Uid=\"MouseUtils_AutoActivate\" IsChecked=\"{x:Bind ViewModel.MouseHighlighterAutoActivate, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"Appearance_Behavior\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEB3C;}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsMouseHighlighterEnabled, Mode=OneWay}\">\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MouseHighlighter_PrimaryButtonClickColor\">\n                                <controls:AlphaColorPickerButton SelectedColor=\"{x:Bind Path=ViewModel.MouseHighlighterLeftButtonClickColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MouseHighlighter_SecondaryButtonClickColor\">\n                                <controls:AlphaColorPickerButton SelectedColor=\"{x:Bind Path=ViewModel.MouseHighlighterRightButtonClickColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MouseHighlighter_AlwaysColor\">\n                                <controls:AlphaColorPickerButton SelectedColor=\"{x:Bind Path=ViewModel.MouseHighlighterAlwaysColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MouseHighlighter_HighlightRadius\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"10\"\n                                    Minimum=\"5\"\n                                    SmallChange=\"1\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MouseHighlighterRadius, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MouseHighlighter_FadeDelayMs\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"100\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"10\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MouseHighlighterFadeDelayMs, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MouseHighlighter_FadeDurationMs\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"100\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"10\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MouseHighlighterFadeDurationMs, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                </controls:SettingsGroup>\n\n                <panels:MouseJumpPanel x:Name=\"MouseUtils_MouseJump_Panel\" x:Uid=\"MouseUtils_MouseJump_Panel\" />\n\n                <controls:SettingsGroup x:Uid=\"MouseUtils_MousePointerCrosshairs\">\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"MouseUtils_Enable_MousePointerCrosshairs\"\n                        HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseCrosshairs.png}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsMousePointerCrosshairsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsMousePointerCrosshairsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <InfoBar\n                        x:Uid=\"GPO_SettingIsManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.IsMousePointerCrosshairsEnabledGpoConfigured, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.IsMousePointerCrosshairsEnabledGpoConfigured, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"MouseUtils_MousePointerCrosshairs_ActivationShortcut\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsMousePointerCrosshairsEnabled, Mode=OneWay}\"\n                        IsExpanded=\"True\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.MousePointerCrosshairsActivationShortcut, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <CheckBox x:Uid=\"MouseUtils_AutoActivate\" IsChecked=\"{x:Bind ViewModel.MousePointerCrosshairsAutoActivate, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"Appearance_Behavior\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEB3C;}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsMousePointerCrosshairsEnabled, Mode=OneWay}\">\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsColor\">\n                                <controls:ColorPickerButton SelectedColor=\"{x:Bind Path=ViewModel.MousePointerCrosshairsColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsOpacity\">\n                                <Slider\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    Maximum=\"100\"\n                                    Minimum=\"1\"\n                                    Value=\"{x:Bind ViewModel.MousePointerCrosshairsOpacity, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsRadius\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"10\"\n                                    Maximum=\"500\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"1\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MousePointerCrosshairsRadius, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsThickness\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"10\"\n                                    Maximum=\"50\"\n                                    Minimum=\"1\"\n                                    SmallChange=\"1\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MousePointerCrosshairsThickness, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsBorderColor\">\n                                <controls:ColorPickerButton SelectedColor=\"{x:Bind Path=ViewModel.MousePointerCrosshairsBorderColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsBorderSize\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"2\"\n                                    Maximum=\"50\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"1\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MousePointerCrosshairsBorderSize, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <CheckBox x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsAutoHide\" IsChecked=\"{x:Bind ViewModel.MousePointerCrosshairsAutoHide, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_IsCrosshairsFixedLengthEnabled\">\n                                <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.MousePointerCrosshairsIsFixedLengthEnabled, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n\n                            <tkcontrols:SettingsCard x:Uid=\"MouseUtils_MousePointerCrosshairs_CrosshairsFixedLength\" IsEnabled=\"{x:Bind ViewModel.MousePointerCrosshairsIsFixedLengthEnabled, Mode=OneWay}\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"10\"\n                                    Minimum=\"1\"\n                                    SmallChange=\"1\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MousePointerCrosshairsFixedLength, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                </controls:SettingsGroup>\n            </StackPanel>\n        </controls:SettingsPageControl.ModuleContent>\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_MouseUtils\" Link=\"https://aka.ms/PowerToysOverview_MouseUtilities\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://devblogs.microsoft.com/oldnewthing/author/oldnewthing\" Text=\"Raymond Chen 的软件 Find My Mouse\" />\n            <controls:PageLink Link=\"https://michael-clayton.com/projects/fancymouse\" Text=\"Michael Clayton 的软件 Mouse Jump (FancyMouse)\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/MouseWithoutBordersPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.MouseWithoutBordersPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:converters=\"using:CommunityToolkit.WinUI.UI.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n    <Page.Resources>\n        <converters:BoolToVisibilityConverter x:Key=\"negativeBoolToVisibilityConverter\" />\n        <converters:BoolToObjectConverter\n            x:Key=\"OneRowMatrixBoolToNumberOfRowsConverter\"\n            FalseValue=\"2\"\n            TrueValue=\"4\" />\n    </Page.Resources>\n    <controls:SettingsPageControl x:Uid=\"MouseWithoutBorders\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/MouseWithoutBorders.png\">\n        <controls:SettingsPageControl.ModuleContent>\n            <StackPanel Orientation=\"Vertical\">\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_ActivationSettings\">\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"MouseWithoutBorders_Toggle_Enable\"\n                        HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/MouseWithoutBorders.png}\"\n                        IsEnabled=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.CanBeEnabled, Mode=OneWay}\"\n                            IsOn=\"{x:Bind ViewModel.IsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <InfoBar\n                        x:Uid=\"GPO_SettingIsManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_KeySettings\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsExpander\n                        x:Name=\"MouseWithoutBorders_ConnectSettings\"\n                        x:Uid=\"MouseWithoutBorders_SecurityKey\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE8D7;}\"\n                        IsExpanded=\"{x:Bind ViewModel.ConnectFieldsVisible, Mode=TwoWay}\">\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Right\">\n                                <StackPanel Orientation=\"Horizontal\" Spacing=\"8\">\n                                    <TextBox\n                                        x:Name=\"ConnectSecurityKeyTextBox\"\n                                        x:Uid=\"MWB_SecurityKeyLabel\"\n                                        Width=\"248\" />\n                                    <TextBox\n                                        x:Name=\"ConnectPCNameTextBox\"\n                                        x:Uid=\"MWB_PCNameLabel\"\n                                        Width=\"248\" />\n                                    <Button\n                                        x:Uid=\"MouseWithoutBorders_Connect\"\n                                        Command=\"{x:Bind ConnectCommand, Mode=OneTime}\"\n                                        Style=\"{StaticResource AccentButtonStyle}\" />\n                                </StackPanel>\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                        <StackPanel Orientation=\"Horizontal\" Spacing=\"8\">\n                            <TextBox IsReadOnly=\"True\" Text=\"{x:Bind ViewModel.SecurityKey, Mode=TwoWay}\" />\n                            <Button\n                                x:Uid=\"MouseWithoutBorders_NewKey\"\n                                Command=\"{x:Bind GenerateNewKeyCommand, Mode=OneTime}\"\n                                Style=\"{StaticResource AccentButtonStyle}\" />\n                            <Button\n                                x:Uid=\"MouseWithoutBorders_Connect\"\n                                Command=\"{x:Bind ShowConnectFieldsCommand, Mode=OneTime}\"\n                                Style=\"{StaticResource AccentButtonStyle}\"\n                                Visibility=\"{x:Bind Path=ViewModel.ConnectFieldsVisible, Mode=OneWay, Converter={StaticResource negativeBoolToVisibilityConverter}, ConverterParameter=True}\" />\n                        </StackPanel>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_ThisMachineNameLabel\">\n                        <StackPanel Orientation=\"Horizontal\" Spacing=\"8\">\n                            <TextBlock\n                                VerticalAlignment=\"Center\"\n                                Foreground=\"{ThemeResource TextFillColorSecondaryBrush}\"\n                                IsTextSelectionEnabled=\"True\"\n                                Text=\"{x:Bind ViewModel.MachineHostName, Mode=OneTime}\" />\n                            <Button\n                                Width=\"32\"\n                                Height=\"32\"\n                                Padding=\"4\"\n                                Command=\"{x:Bind CopyPCNameCommand, Mode=OneTime}\"\n                                Content=\"&#xE8C8;\"\n                                FontFamily=\"{StaticResource SymbolThemeFontFamily}\">\n                                <ToolTipService.ToolTip>\n                                    <TextBlock x:Uid=\"MouseWithoutBorders_CopyMachineName\" TextWrapping=\"Wrap\" />\n                                </ToolTipService.ToolTip>\n                            </Button>\n                        </StackPanel>\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_DeviceLayoutSettings\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard\n                        HorizontalContentAlignment=\"Stretch\"\n                        Background=\"{ThemeResource CardBackgroundFillColorSecondaryBrush}\"\n                        ContentAlignment=\"Vertical\">\n                        <StackPanel Orientation=\"Vertical\" Spacing=\"8\">\n                            <ItemsControl\n                                x:Name=\"DevicesItemsControl\"\n                                HorizontalAlignment=\"Center\"\n                                ItemsSource=\"{Binding MachineMatrixString, Mode=TwoWay}\">\n                                <ItemsControl.ItemsPanel>\n                                    <ItemsPanelTemplate>\n                                        <WrapGrid MaximumRowsOrColumns=\"{Binding MatrixOneRow, Mode=OneWay, Converter={StaticResource OneRowMatrixBoolToNumberOfRowsConverter}}\" Orientation=\"Horizontal\" />\n                                    </ItemsPanelTemplate>\n                                </ItemsControl.ItemsPanel>\n                                <ItemsControl.ItemTemplate>\n                                    <DataTemplate>\n                                        <!--  TODO: colors?  -->\n                                        <!--\n                                            BorderBrush=\"#DFDFDF\"\n                                            Background=\"#d4d4d4\"\n                                        -->\n                                        <!--  Dragging while elevated crashes on WinUI3: https://github.com/microsoft/microsoft-ui-xaml/issues/7690  -->\n                                        <Border\n                                            Width=\"136\"\n                                            Height=\"90\"\n                                            Margin=\"4\"\n                                            AllowDrop=\"{Binding Item.CanDragDrop, Mode=OneWay}\"\n                                            Background=\"{ThemeResource SolidBackgroundFillColorBaseAltBrush}\"\n                                            BorderBrush=\"{Binding Item.StatusBrush}\"\n                                            BorderThickness=\"2\"\n                                            CanDrag=\"{Binding Item.CanDragDrop, Mode=OneWay}\"\n                                            CornerRadius=\"4\"\n                                            DataContext=\"{Binding}\"\n                                            DragOver=\"Device_DragOver\"\n                                            DragStarting=\"Device_DragStarting\"\n                                            Drop=\"Device_Drop\"\n                                            ToolTipService.ToolTip=\"{Binding Item.Name, Mode=OneWay}\">\n                                            <Grid>\n                                                <Grid.RowDefinitions>\n                                                    <RowDefinition Height=\"*\" />\n                                                    <RowDefinition Height=\"Auto\" />\n                                                </Grid.RowDefinitions>\n\n                                                <FontIcon\n                                                    Margin=\"0,12,0,0\"\n                                                    VerticalAlignment=\"Center\"\n                                                    FontSize=\"32\"\n                                                    Glyph=\"&#xE7F8;\" />\n                                                <TextBlock\n                                                    Grid.Row=\"1\"\n                                                    Margin=\"12\"\n                                                    HorizontalAlignment=\"Center\"\n                                                    Style=\"{StaticResource CaptionTextBlockStyle}\"\n                                                    Tag=\"DeviceName\"\n                                                    Text=\"{Binding Item.Name}\" />\n                                            </Grid>\n                                        </Border>\n                                    </DataTemplate>\n                                </ItemsControl.ItemTemplate>\n                            </ItemsControl>\n                            <Button HorizontalAlignment=\"Right\" Command=\"{x:Bind ReconnectCommand, Mode=OneTime}\">\n                                <ToolTipService.ToolTip>\n                                    <TextBlock x:Uid=\"MouseWithoutBorders_ReconnectTooltip\" TextWrapping=\"Wrap\" />\n                                </ToolTipService.ToolTip>\n                                <TextBlock x:Uid=\"MouseWithoutBorders_ReconnectButton\" />\n                            </Button>\n\n\n                        </StackPanel>\n                    </tkcontrols:SettingsCard>\n\n                    <InfoBar\n                        x:Uid=\"MouseWithoutBorders_CannotDragDropAsAdmin\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.ShowInfobarCannotDragDropAsAdmin, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.ShowInfobarCannotDragDropAsAdmin, Mode=OneWay}\"\n                        Severity=\"Informational\" />\n\n\n\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_MatrixOneRow\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_MatrixOneRow_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.MatrixOneRow, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_ServiceSettings\" IsEnabled=\"{x:Bind ViewModel.CanToggleUseService, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_UseService\">\n                        <ToggleSwitch\n                            x:Uid=\"MouseWithoutBorders_UseService_ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\"\n                            IsOn=\"{x:Bind ViewModel.UseService, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <InfoBar\n                        x:Uid=\"MouseWithoutBorders_RunAsAdminText\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.ShowInfobarRunAsAdminText, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.ShowInfobarRunAsAdminText, Mode=OneWay}\"\n                        Severity=\"Informational\" />\n                    <InfoBar\n                        x:Uid=\"MouseWithoutBorders_ServiceUserUninstallWarning\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\"\n                        Severity=\"Warning\" />\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"MouseWithoutBorders_UninstallService\"\n                        ActionIcon=\"{ui:FontIcon Glyph=&#xE8A7;}\"\n                        Command=\"{x:Bind ViewModel.UninstallServiceEventHandler}\"\n                        IsClickEnabled=\"{x:Bind ViewModel.CanUninstallService, Mode=OneWay}\"\n                        IsEnabled=\"{x:Bind ViewModel.CanUninstallService, Mode=OneWay}\" />\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_Settings\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <InfoBar\n                        x:Uid=\"GPO_SomeSettingsAreManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.ShowPolicyConfiguredInfoForBehaviorSettings, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.ShowPolicyConfiguredInfoForBehaviorSettings, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_WrapMouse\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_WrapMouse_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.WrapMouse, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"MouseWithoutBorders_ShareClipboard\"\n                        IsEnabled=\"{x:Bind ViewModel.CardForShareClipboardSettingIsEnabled, Mode=OneWay}\"\n                        IsExpanded=\"True\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_ShareClipboard_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.ShareClipboard, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_TransferFile\" IsEnabled=\"{x:Bind ViewModel.CardForTransferFileSettingIsEnabled, Mode=OneWay}\">\n                                <ToggleSwitch x:Uid=\"MouseWithoutBorders_TransferFile_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.TransferFile, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_HideMouseAtScreenEdge\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_HideMouseAtScreenEdge_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.HideMouseAtScreenEdge, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_DrawMouseCursor\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_DrawMouseCursor_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.DrawMouseCursor, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_ValidateRemoteMachineIP\" IsEnabled=\"{x:Bind ViewModel.CardForValidateRemoteIpSettingIsEnabled, Mode=OneWay}\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_ValidateRemoteMachineIP_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.ValidateRemoteMachineIP, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_SameSubnetOnly\" IsEnabled=\"{x:Bind ViewModel.CardForSameSubnetOnlySettingIsEnabled, Mode=OneWay}\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_SameSubnetOnly_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.SameSubnetOnly, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_BlockScreenSaverOnOtherMachines\" IsEnabled=\"{x:Bind ViewModel.CardForBlockScreensaverSettingIsEnabled, Mode=OneWay}\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_BlockScreenSaverOnOtherMachines_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.BlockScreenSaverOnOtherMachines, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_MoveMouseRelatively\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_MoveMouseRelatively_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.MoveMouseRelatively, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_BlockMouseAtScreenCorners\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_BlockMouseAtScreenCorners_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.BlockMouseAtScreenCorners, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.ShowClipboardAndNetworkStatusMessages, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_KeyboardShortcuts_Group\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_EasyMouseOption\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE962;}\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind Path=ViewModel.EasyMouseOptionIndex, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"MouseWithoutBorders_EasyMouseOption_Disabled\" />\n                            <ComboBoxItem x:Uid=\"MouseWithoutBorders_EasyMouseOption_Enabled\" />\n                            <ComboBoxItem x:Uid=\"MouseWithoutBorders_EasyMouseOption_Ctrl\" />\n                            <ComboBoxItem x:Uid=\"MouseWithoutBorders_EasyMouseOption_Shift\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_ToggleEasyMouseShortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            AllowDisable=\"True\"\n                            HotkeySettings=\"{x:Bind Path=ViewModel.ToggleEasyMouseShortcut, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_LockMachinesShortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            AllowDisable=\"True\"\n                            HotkeySettings=\"{x:Bind Path=ViewModel.LockMachinesShortcut, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_Switch2AllPcShortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            AllowDisable=\"True\"\n                            HotkeySettings=\"{x:Bind Path=ViewModel.HotKeySwitch2AllPC, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_ReconnectShortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            AllowDisable=\"True\"\n                            HotkeySettings=\"{x:Bind Path=ViewModel.ReconnectShortcut, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_SwitchBetweenMachineShortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind Path=ViewModel.SelectedSwitchBetweenMachineShortcutOptionsIndex, Mode=TwoWay}\">\n                            <!--  These should be in the same order as the array items in MouseWithoutBordersViewModel.cs  -->\n                            <ComboBoxItem x:Uid=\"MouseWithoutBorders_SwitchBetweenMachineShortcut_F1\" />\n                            <ComboBoxItem x:Uid=\"MouseWithoutBorders_SwitchBetweenMachineShortcut_1\" />\n                            <ComboBoxItem x:Uid=\"MouseWithoutBorders_SwitchBetweenMachineShortcut_Disabled\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_AdvancedSettings_Group\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsExpander x:Uid=\"MouseWithoutBorders_IPAddressMapping\" IsExpanded=\"True\">\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard\n                                HorizontalContentAlignment=\"Stretch\"\n                                ContentAlignment=\"Vertical\"\n                                IsEnabled=\"{x:Bind ViewModel.CardForName2IpSettingIsEnabled, Mode=OneWay}\">\n                                <TextBox\n                                    x:Uid=\"MouseWithoutBorders_IPAddressMapping_TextBoxControl\"\n                                    MinWidth=\"240\"\n                                    MinHeight=\"160\"\n                                    MaxHeight=\"480\"\n                                    AcceptsReturn=\"True\"\n                                    ScrollViewer.IsVerticalRailEnabled=\"True\"\n                                    ScrollViewer.VerticalScrollBarVisibility=\"Visible\"\n                                    ScrollViewer.VerticalScrollMode=\"Enabled\"\n                                    Text=\"{x:Bind ViewModel.Name2IP, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\"\n                                    TextWrapping=\"Wrap\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard\n                                Padding=\"0\"\n                                HorizontalContentAlignment=\"Stretch\"\n                                Background=\"{ThemeResource InfoBarInformationalSeverityBackgroundBrush}\"\n                                ContentAlignment=\"Vertical\"\n                                Visibility=\"{x:Bind ViewModel.ShowPolicyConfiguredInfoForName2IPSetting, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\">\n                                <InfoBar\n                                    x:Uid=\"GPO_SettingIsManaged\"\n                                    Background=\"Transparent\"\n                                    BorderBrush=\"Transparent\"\n                                    IsClosable=\"False\"\n                                    IsOpen=\"True\"\n                                    IsTabStop=\"{x:Bind ViewModel.ShowPolicyConfiguredInfoForName2IPSetting, Mode=OneWay}\"\n                                    Severity=\"Informational\">\n                                    <InfoBar.IconSource>\n                                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                                    </InfoBar.IconSource>\n                                </InfoBar>\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard\n                                Margin=\"0,1,0,0\"\n                                Padding=\"0\"\n                                HorizontalContentAlignment=\"Stretch\"\n                                Background=\"{ThemeResource InfoBarInformationalSeverityBackgroundBrush}\"\n                                ContentAlignment=\"Vertical\"\n                                Visibility=\"{x:Bind ViewModel.Name2IpListPolicyIsConfigured, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\">\n                                <InfoBar\n                                    x:Uid=\"MouseWithoutBorders_PolicyIPAddressMappingInfo\"\n                                    Background=\"Transparent\"\n                                    BorderBrush=\"Transparent\"\n                                    IsClosable=\"False\"\n                                    IsOpen=\"True\"\n                                    IsTabStop=\"{x:Bind ViewModel.Name2IpListPolicyIsConfigured, Mode=OneWay}\"\n                                    Severity=\"Informational\">\n                                    <InfoBar.IconSource>\n                                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                                    </InfoBar.IconSource>\n                                    <InfoBar.Content>\n                                        <TextBox\n                                            x:Uid=\"MouseWithoutBorders_PolicyIPAddressMappingInfo_TextBoxControl\"\n                                            MinWidth=\"240\"\n                                            MinHeight=\"80\"\n                                            MaxHeight=\"160\"\n                                            Margin=\"0,0,44,16\"\n                                            AcceptsReturn=\"True\"\n                                            IsReadOnly=\"True\"\n                                            ScrollViewer.IsVerticalRailEnabled=\"True\"\n                                            ScrollViewer.VerticalScrollBarVisibility=\"Visible\"\n                                            ScrollViewer.VerticalScrollMode=\"Enabled\"\n                                            Text=\"{x:Bind ViewModel.Name2IpListPolicyData, Mode=OneWay}\"\n                                            TextWrapping=\"Wrap\" />\n                                    </InfoBar.Content>\n                                </InfoBar>\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"MouseWithoutBorders_TroubleShooting\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"MouseWithoutBorders_AddFirewallRuleButtonControl\"\n                        ActionIcon=\"{ui:FontIcon Glyph=&#xE8A7;}\"\n                        Command=\"{x:Bind ViewModel.AddFirewallRuleEventHandler}\"\n                        IsClickEnabled=\"True\" />\n                    <tkcontrols:SettingsCard x:Uid=\"MouseWithoutBorders_ShowOriginalUI\" IsEnabled=\"{x:Bind ViewModel.CardForOriginalUiSettingIsEnabled, Mode=OneWay}\">\n                        <ToggleSwitch x:Uid=\"MouseWithoutBorders_ShowOriginalUI_ToggleSwitch\" IsOn=\"{x:Bind ViewModel.ShowOriginalUI, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <InfoBar\n                        x:Uid=\"GPO_SettingIsManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.ShowPolicyConfiguredInfoForOriginalUiSetting, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.ShowPolicyConfiguredInfoForOriginalUiSetting, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n                </controls:SettingsGroup>\n            </StackPanel>\n        </controls:SettingsPageControl.ModuleContent>\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_MouseWithoutBorders\" Link=\"https://aka.ms/PowerToysOverview_MouseWithoutBorders\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"http://aka.ms/mm\" Text=\"微软无界鼠标\" />\n            <controls:PageLink Link=\"https://github.com/microsoft/PowerToys/blob/main/COMMUNITY.md#mouse-without-borders-original-contributors\" Text=\"Truong Do (Đỗ Đức Trường) 等原软件作者\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerLauncherPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.PowerLauncherPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:ViewModels=\"using:Microsoft.PowerToys.Settings.UI.ViewModels\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:converters=\"using:Microsoft.PowerToys.Settings.UI.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:i=\"using:Microsoft.Xaml.Interactivity\"\n    xmlns:ic=\"using:Microsoft.Xaml.Interactions.Core\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n\n    <Page.Resources>\n        <Style x:Key=\"OptionSeparator\" TargetType=\"Rectangle\">\n            <Setter Property=\"Height\" Value=\"1\" />\n            <Setter Property=\"HorizontalAlignment\" Value=\"Stretch\" />\n            <Setter Property=\"Fill\" Value=\"{ThemeResource CardStrokeColorDefaultBrush}\" />\n        </Style>\n\n        <converters:RunOptionTemplateSelector\n            x:Key=\"RunOptionTemplateSelector\"\n            CheckBoxComboBoxTemplate=\"{StaticResource CheckBoxComboBoxTemplate}\"\n            CheckBoxMultilineTextBoxTemplate=\"{StaticResource CheckBoxMultilineTextBoxTemplate}\"\n            CheckBoxNumberBoxTemplate=\"{StaticResource CheckBoxNumberBoxTemplate}\"\n            CheckBoxTemplate=\"{StaticResource CheckBoxTemplate}\"\n            CheckBoxTextBoxTemplate=\"{StaticResource CheckBoxTextBoxTemplate}\"\n            ComboBoxTemplate=\"{StaticResource ComboBoxTemplate}\"\n            EmptyTemplate=\"{StaticResource EmptyTemplate}\"\n            MultilineTextBoxTemplate=\"{StaticResource MultilineTextBoxTemplate}\"\n            NumberBoxTemplate=\"{StaticResource NumberBoxTemplate}\"\n            TextboxTemplate=\"{StaticResource TextBoxTemplate}\" />\n\n        <DataTemplate x:Key=\"CheckBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"1\"\n                    Padding=\"0,6,0,12\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    ContentAlignment=\"Left\"\n                    CornerRadius=\"0\">\n                    <controls:CheckBoxWithDescriptionControl\n                        Margin=\"56,0,0,0\"\n                        Description=\"{x:Bind Path=DisplayDescription}\"\n                        Header=\"{x:Bind Path=DisplayLabel}\"\n                        IsChecked=\"{x:Bind Value, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"ComboBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"56,8,45,8\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=DisplayDescription}\"\n                    Header=\"{x:Bind Path=DisplayLabel}\">\n                    <ComboBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        DisplayMemberPath=\"Key\"\n                        ItemsSource=\"{x:Bind Path=ComboBoxItems}\"\n                        SelectedValue=\"{x:Bind ComboBoxValue, Mode=TwoWay}\"\n                        SelectedValuePath=\"Value\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"TextBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"56,8,45,8\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=DisplayDescription}\"\n                    Header=\"{x:Bind Path=DisplayLabel}\">\n                    <TextBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        MaxWidth=\"450\"\n                        MaxLength=\"{x:Bind TextBoxMaxLength, Mode=OneWay}\"\n                        PlaceholderText=\"{x:Bind Path=PlaceholderText}\"\n                        Text=\"{x:Bind TextValue, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"NumberBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"56,8,45,8\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=DisplayDescription}\"\n                    Header=\"{x:Bind Path=DisplayLabel}\">\n                    <NumberBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        LargeChange=\"{x:Bind NumberBoxLargeChange, Mode=OneWay}\"\n                        Maximum=\"{x:Bind NumberBoxMax, Mode=OneWay}\"\n                        Minimum=\"{x:Bind NumberBoxMin, Mode=OneWay}\"\n                        SmallChange=\"{x:Bind NumberBoxSmallChange, Mode=OneWay}\"\n                        SpinButtonPlacementMode=\"Compact\"\n                        Value=\"{x:Bind NumberValue, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"MultilineTextBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"56,8,45,8\"\n                    HorizontalContentAlignment=\"Stretch\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    ContentAlignment=\"Vertical\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=DisplayDescription}\"\n                    Header=\"{x:Bind Path=DisplayLabel}\">\n                    <TextBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        MinHeight=\"160\"\n                        AcceptsReturn=\"True\"\n                        PlaceholderText=\"{x:Bind Path=PlaceholderText}\"\n                        ScrollViewer.IsVerticalRailEnabled=\"True\"\n                        ScrollViewer.VerticalScrollBarVisibility=\"Visible\"\n                        ScrollViewer.VerticalScrollMode=\"Enabled\"\n                        Text=\"{x:Bind TextValue, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"CheckBoxComboBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"1\"\n                    Padding=\"0,6,0,4\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    ContentAlignment=\"Left\"\n                    CornerRadius=\"0\">\n                    <controls:CheckBoxWithDescriptionControl\n                        Margin=\"56,0,0,0\"\n                        Description=\"{x:Bind Path=DisplayDescription}\"\n                        Header=\"{x:Bind Path=DisplayLabel}\"\n                        IsChecked=\"{x:Bind Value, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"84,0,45,8\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=SecondDisplayDescription}\"\n                    Header=\"{x:Bind Path=SecondDisplayLabel}\"\n                    IsEnabled=\"{x:Bind SecondSettingIsEnabled, Mode=OneWay}\">\n                    <ComboBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        DisplayMemberPath=\"Key\"\n                        ItemsSource=\"{x:Bind Path=ComboBoxItems}\"\n                        SelectedValue=\"{x:Bind ComboBoxValue, Mode=TwoWay}\"\n                        SelectedValuePath=\"Value\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"CheckBoxTextBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"1\"\n                    Padding=\"0,6,0,4\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    ContentAlignment=\"Left\"\n                    CornerRadius=\"0\">\n                    <controls:CheckBoxWithDescriptionControl\n                        Margin=\"56,0,0,0\"\n                        Description=\"{x:Bind Path=DisplayDescription}\"\n                        Header=\"{x:Bind Path=DisplayLabel}\"\n                        IsChecked=\"{x:Bind Value, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"84,0,45,8\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=SecondDisplayDescription}\"\n                    Header=\"{x:Bind Path=SecondDisplayLabel}\"\n                    IsEnabled=\"{x:Bind SecondSettingIsEnabled, Mode=OneWay}\">\n                    <TextBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        MaxWidth=\"450\"\n                        MaxLength=\"{x:Bind TextBoxMaxLength, Mode=OneWay}\"\n                        PlaceholderText=\"{x:Bind Path=PlaceholderText}\"\n                        Text=\"{x:Bind TextValue, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"CheckBoxMultilineTextBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"1\"\n                    Padding=\"0,6,0,4\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    ContentAlignment=\"Left\"\n                    CornerRadius=\"0\">\n                    <controls:CheckBoxWithDescriptionControl\n                        Margin=\"56,0,0,0\"\n                        Description=\"{x:Bind Path=DisplayDescription}\"\n                        Header=\"{x:Bind Path=DisplayLabel}\"\n                        IsChecked=\"{x:Bind Value, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"84,0,45,8\"\n                    HorizontalContentAlignment=\"Stretch\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    ContentAlignment=\"Vertical\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=SecondDisplayDescription}\"\n                    Header=\"{x:Bind Path=SecondDisplayLabel}\"\n                    IsEnabled=\"{x:Bind SecondSettingIsEnabled, Mode=OneWay}\">\n                    <TextBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        MinHeight=\"160\"\n                        AcceptsReturn=\"True\"\n                        PlaceholderText=\"{x:Bind Path=PlaceholderText}\"\n                        ScrollViewer.IsVerticalRailEnabled=\"True\"\n                        ScrollViewer.VerticalScrollBarVisibility=\"Visible\"\n                        ScrollViewer.VerticalScrollMode=\"Enabled\"\n                        Text=\"{x:Bind TextValue, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"CheckBoxNumberBoxTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"1\"\n                    Padding=\"0,6,0,4\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    ContentAlignment=\"Left\"\n                    CornerRadius=\"0\">\n                    <controls:CheckBoxWithDescriptionControl\n                        Margin=\"56,0,0,0\"\n                        Description=\"{x:Bind Path=DisplayDescription}\"\n                        Header=\"{x:Bind Path=DisplayLabel}\"\n                        IsChecked=\"{x:Bind Value, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <tkcontrols:SettingsCard\n                    MinHeight=\"0\"\n                    Margin=\"84,0,45,8\"\n                    Background=\"Transparent\"\n                    BorderThickness=\"0,0,0,0\"\n                    CornerRadius=\"0\"\n                    Description=\"{x:Bind Path=SecondDisplayDescription}\"\n                    Header=\"{x:Bind Path=SecondDisplayLabel}\"\n                    IsEnabled=\"{x:Bind SecondSettingIsEnabled, Mode=OneWay}\">\n                    <NumberBox\n                        MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                        LargeChange=\"{x:Bind NumberBoxLargeChange, Mode=OneWay}\"\n                        Maximum=\"{x:Bind NumberBoxMax, Mode=OneWay}\"\n                        Minimum=\"{x:Bind NumberBoxMin, Mode=OneWay}\"\n                        SmallChange=\"{x:Bind NumberBoxSmallChange, Mode=OneWay}\"\n                        SpinButtonPlacementMode=\"Compact\"\n                        Value=\"{x:Bind NumberValue, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <Rectangle Style=\"{StaticResource OptionSeparator}\" />\n            </StackPanel>\n        </DataTemplate>\n\n        <DataTemplate x:Key=\"EmptyTemplate\" x:DataType=\"ViewModels:PluginAdditionalOptionViewModel\">\n            <StackPanel HorizontalAlignment=\"Stretch\" Orientation=\"Vertical\" />\n        </DataTemplate>\n    </Page.Resources>\n\n    <controls:SettingsPageControl x:Uid=\"PowerLauncher\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/Run.png\">\n        <controls:SettingsPageControl.ModuleContent>\n\n            <StackPanel ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\" Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    x:Uid=\"PowerLauncher_EnablePowerLauncher\"\n                    HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerToysRun.png}\"\n                    IsEnabled=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                    <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.EnablePowerLauncher, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <InfoBar\n                    x:Uid=\"GPO_SettingIsManaged\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    Severity=\"Informational\">\n                    <InfoBar.IconSource>\n                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                    </InfoBar.IconSource>\n                </InfoBar>\n\n                <controls:SettingsGroup x:Uid=\"Shortcut\" IsEnabled=\"{x:Bind ViewModel.EnablePowerLauncher, Mode=OneWay}\">\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"Activation_Shortcut\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\"\n                        IsExpanded=\"True\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.OpenPowerLauncher, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <controls:CheckBoxWithDescriptionControl x:Uid=\"PowerLauncher_UseCentralizedKeyboardHook\" IsChecked=\"{x:Bind ViewModel.UseCentralizedKeyboardHook, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <CheckBox x:Uid=\"PowerLauncher_IgnoreHotkeysInFullScreen\" IsChecked=\"{x:Bind ViewModel.IgnoreHotkeysInFullScreen, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                </controls:SettingsGroup>\n\n\n                <!--<Custom:HotkeySettingsControl x:Uid=\"PowerLauncher_OpenFileLocation\"\n                                          HorizontalAlignment=\"Left\"\n                                          Margin=\"{StaticResource SmallTopMargin}\"\n                                          HotkeySettings=\"{Binding Path=ViewModel.OpenFileLocation, Mode=TwoWay}\"\n                                          IsEnabled=\"False\"\n                                        />\n            <Custom:HotkeySettingsControl x:Uid=\"PowerLauncher_CopyPathLocation\"\n                                          HorizontalAlignment=\"Left\"\n                                          Margin=\"{StaticResource SmallTopMargin}\"\n                                          HotkeySettings=\"{Binding Path=ViewModel.CopyPathLocation, Mode=TwoWay}\"\n                                          Keys=\"Win, Ctrl, Alt, Shift\"\n                                          IsEnabled=\"False\"\n                                        />\n            <Custom:HotkeySettingsControl x:Uid=\"PowerLauncher_OpenConsole\"\n                                          HorizontalAlignment=\"Left\"\n                                          Margin=\"{StaticResource SmallTopMargin}\"\n                                          HotkeySettings=\"{Binding Path=ViewModel.OpenConsole, Mode=TwoWay}\"\n                                          Keys=\"Win, Ctrl, Alt, Shift\"\n                                          IsEnabled=\"False\"\n                                        />-->\n\n                <!--<CheckBox x:Uid=\"PowerLauncher_OverrideWinRKey\"\n                      Margin=\"{StaticResource SmallTopMargin}\"\n                      IsChecked=\"False\"\n                      IsEnabled=\"False\"\n                      />-->\n\n                <!--<CheckBox x:Uid=\"PowerLauncher_OverrideWinSKey\"\n                      Margin=\"{StaticResource SmallTopMargin}\"\n                      IsChecked=\"{x:Bind ViewModel.OverrideWinSKey, Mode=TwoWay}\"\n                      IsEnabled=\"False\"\n                      />-->\n\n                <controls:SettingsGroup x:Uid=\"PowerLauncher_SearchResults\" IsEnabled=\"{x:Bind ViewModel.EnablePowerLauncher, Mode=OneWay}\">\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"PowerLauncher_SearchQueryResultsWithDelay\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xec48;}\"\n                        IsExpanded=\"True\">\n                        <ToggleSwitch IsOn=\"{x:Bind ViewModel.SearchQueryResultsWithDelay, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_FastSearchInputDelayMs\" IsEnabled=\"{x:Bind ViewModel.SearchQueryResultsWithDelay, Mode=OneWay}\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"50\"\n                                    Maximum=\"500\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"10\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.SearchInputDelayFast, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_SlowSearchInputDelayMs\" IsEnabled=\"{x:Bind ViewModel.SearchQueryResultsWithDelay, Mode=OneWay}\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"50\"\n                                    Maximum=\"1000\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"10\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.SearchInputDelay, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"PowerLauncher_MaximumNumberOfResults\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xec8f;}\"\n                        IsExpanded=\"True\">\n                        <NumberBox\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            Minimum=\"1\"\n                            SpinButtonPlacementMode=\"Compact\"\n                            Value=\"{x:Bind ViewModel.MaximumNumberOfResults, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <CheckBox x:Uid=\"PowerLauncher_ClearInputOnLaunch\" IsChecked=\"{x:Bind ViewModel.ClearInputOnLaunch, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"PowerLauncher_SearchQueryTuningEnabled\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE8CB;}\"\n                        IsExpanded=\"True\">\n                        <ToggleSwitch IsOn=\"{x:Bind ViewModel.SearchQueryTuningEnabled, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_SearchClickedItemWeight\" IsEnabled=\"{x:Bind ViewModel.SearchQueryTuningEnabled, Mode=OneWay}\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    LargeChange=\"50\"\n                                    Maximum=\"1000\"\n                                    Minimum=\"0\"\n                                    SmallChange=\"5\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.SearchClickedItemWeight, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\" IsEnabled=\"{x:Bind ViewModel.SearchQueryTuningEnabled, Mode=OneWay}\">\n                                <controls:CheckBoxWithDescriptionControl x:Uid=\"PowerLauncher_WaitForSlowResults\" IsChecked=\"{x:Bind ViewModel.SearchWaitForSlowResults, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_TabSelectsContextButtons\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE7FD;}\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.TabSelectsContextButtons, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_UsePinyin\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE98A;}\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.UsePinyin, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_GenerateThumbnailsFromFiles\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE91B;}\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.GenerateThumbnailsFromFiles, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n\n                <!--<ComboBox x:Uid=\"PowerLauncher_SearchResultPreference\"\n                      MinWidth=\"320\"\n                      Margin=\"{StaticResource SmallTopMargin}\"\n                      ItemsSource=\"{Binding searchResultPreferencesOptions}\"\n                      SelectedItem=\"{x:Bind SelectedSearchResultPreference, Mode=TwoWay}\"\n                      SelectedValuePath=\"Item2\"\n                      DisplayMemberPath=\"Item1\"\n                      IsEnabled=\"False\"\n                      />\n\n            <ComboBox x:Uid=\"PowerLauncher_SearchTypePreference\"\n                      MinWidth=\"320\"\n                      Margin=\"{StaticResource SmallTopMargin}\"\n                      ItemsSource=\"{Binding searchTypePreferencesOptions}\"\n                      SelectedItem=\"{x:Bind SelectedSearchTypePreference, Mode=TwoWay}\"\n                      SelectedValuePath=\"Item2\"\n                      DisplayMemberPath=\"Item1\"\n                      IsEnabled=\"False\"\n                      />-->\n\n                <controls:SettingsGroup x:Uid=\"Run_PositionAppearance_GroupSettings\" IsEnabled=\"{x:Bind ViewModel.EnablePowerLauncher, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"Run_PositionHeader\" HeaderIcon=\"{ui:FontIcon Glyph=&#xe78b;}\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.MonitorPositionIndex, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"Run_Radio_Position_Cursor\" />\n                            <ComboBoxItem x:Uid=\"Run_Radio_Position_Primary_Monitor\" />\n                            <ComboBoxItem x:Uid=\"Run_Radio_Position_Focus\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"ColorModeHeader\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE790;}\">\n                        <tkcontrols:SettingsCard.Description>\n                            <HyperlinkButton x:Uid=\"Windows_Color_Settings\" Click=\"OpenColorsSettings_Click\" />\n                        </tkcontrols:SettingsCard.Description>\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.ThemeIndex, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"Radio_Theme_Dark\" />\n                            <ComboBoxItem x:Uid=\"Radio_Theme_Light\" />\n                            <ComboBoxItem x:Uid=\"Radio_Theme_Default\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_ShowPluginKeywords\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE8FD;}\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.ShowPluginsOverviewIndex, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"ShowPluginsOverview_All\" />\n                            <ComboBoxItem x:Uid=\"ShowPluginsOverview_NonGlobal\" />\n                            <ComboBoxItem x:Uid=\"ShowPluginsOverview_None\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_TitleFontSize\" HeaderIcon=\"{ui:FontIcon Glyph=&#xE8E9;}\">\n                        <StackPanel Orientation=\"Horizontal\" Spacing=\"12\">\n                            <TextBlock\n                                VerticalAlignment=\"Center\"\n                                AutomationProperties.AccessibilityView=\"Raw\"\n                                FontSize=\"12\"\n                                FontWeight=\"SemiBold\"\n                                Text=\"A\" />\n                            <Slider\n                                x:Uid=\"PowerLauncher_TextFontSizeSlider\"\n                                LargeChange=\"2\"\n                                Maximum=\"24\"\n                                Minimum=\"12\"\n                                SmallChange=\"2\"\n                                StepFrequency=\"2\"\n                                TickFrequency=\"2\"\n                                TickPlacement=\"Outside\"\n                                Value=\"{x:Bind ViewModel.TitleFontSize, Mode=TwoWay}\" />\n                            <TextBlock\n                                VerticalAlignment=\"Center\"\n                                AutomationProperties.AccessibilityView=\"Raw\"\n                                FontSize=\"24\"\n                                FontWeight=\"SemiBold\"\n                                Text=\"A\" />\n                        </StackPanel>\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"PowerLauncher_Plugins\" IsEnabled=\"{x:Bind ViewModel.EnablePowerLauncher, Mode=OneWay}\">\n\n                    <InfoBar\n                        x:Uid=\"Run_ConflictingKeywordInfo\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.EnablePowerLauncher, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.EnablePowerLauncher, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.ActionButton>\n                            <HyperlinkButton x:Uid=\"Run_ConflictingKeywordInfo_Link\" NavigateUri=\"https://aka.ms/PowerToysOverview_PowerToysRun#direct-activation-commands\" />\n                        </InfoBar.ActionButton>\n                    </InfoBar>\n\n                    <tkcontrols:SettingsCard x:Uid=\"Run_PluginUse\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEA86;}\">\n                        <tkcontrols:SettingsCard.Description>\n                            <StackPanel>\n                                <TextBlock x:Uid=\"Run_PluginUseDescription\" />\n                                <HyperlinkButton x:Uid=\"Run_PluginUseFindMorePlugins\" NavigateUri=\"https://aka.ms/powerToysRunPlugins\" />\n                            </StackPanel>\n                        </tkcontrols:SettingsCard.Description>\n                        <AutoSuggestBox\n                            x:Uid=\"PowerLauncher_SearchList\"\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            QueryIcon=\"Find\"\n                            Text=\"{x:Bind ViewModel.SearchText, Mode=TwoWay}\">\n                            <i:Interaction.Behaviors>\n                                <ic:EventTriggerBehavior EventName=\"TextChanged\">\n                                    <ic:InvokeCommandAction Command=\"{x:Bind ViewModel.SearchPluginsCommand}\" />\n                                </ic:EventTriggerBehavior>\n                            </i:Interaction.Behaviors>\n                        </AutoSuggestBox>\n                    </tkcontrols:SettingsCard>\n\n\n                    <InfoBar\n                        x:Uid=\"GPO_SomeRunPluginsAreManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.ShowPluginsAreGpoManagedInfo, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.ShowPluginsAreGpoManagedInfo, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n                    <InfoBar\n                        x:Uid=\"Run_AllPluginsDisabled\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.ShowAllPluginsDisabledWarning, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.ShowAllPluginsDisabledWarning, Mode=OneWay}\"\n                        Severity=\"Error\" />\n\n                    <StackPanel Orientation=\"Horizontal\" Visibility=\"{x:Bind ViewModel.ShowPluginsLoadingMessage, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\">\n                        <ProgressRing\n                            Width=\"20\"\n                            Height=\"20\"\n                            Margin=\"18,18\"\n                            IsActive=\"True\" />\n                        <TextBlock\n                            x:Uid=\"Run_PluginsLoading\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{ThemeResource SecondaryTextStyle}\" />\n                    </StackPanel>\n\n                    <ItemsRepeater x:Name=\"PluginsListView\" ItemsSource=\"{x:Bind Path=ViewModel.Plugins, Mode=OneWay}\">\n                        <ItemsRepeater.Layout>\n                            <StackLayout Spacing=\"2\" />\n                        </ItemsRepeater.Layout>\n                        <ItemsRepeater.ItemTemplate>\n                            <DataTemplate x:DataType=\"ViewModels:PowerLauncherPluginViewModel\" x:DefaultBindMode=\"OneWay\">\n                                <Grid>\n                                    <tkcontrols:SettingsExpander Description=\"{x:Bind Description}\" Header=\"{x:Bind Path=Name}\">\n                                        <tkcontrols:SettingsExpander.HeaderIcon>\n                                            <BitmapIcon UriSource=\"{x:Bind IconPath}\" />\n                                        </tkcontrols:SettingsExpander.HeaderIcon>\n                                        <StackPanel Orientation=\"Horizontal\" Spacing=\"16\">\n                                            <!-- todo(Stefan): InfoBadge not available\n                                                        <InfoBadge AutomationProperties.AccessibilityView=\"Raw\"\n                                                                        Visibility=\"{x:Bind ShowBadgeOnPluginSettingError}\"\n                                                                        Style=\"{StaticResource CriticalIconInfoBadgeStyle}\" />\n                                            -->\n\n                                            <!--  Temporary badge replacement for InfoBadge control (htcfreek). (Normally you need one grid per icon group. But if you want to show two badges at the same place in a StackPanel you have to put all FontIcons into the same Grid.)  -->\n                                            <Grid>\n                                                <!--  Error badge  -->\n                                                <FontIcon\n                                                    FontFamily=\"{StaticResource SymbolThemeFontFamily}\"\n                                                    Foreground=\"{ThemeResource InfoBarErrorSeverityIconBackground}\"\n                                                    Glyph=\"{StaticResource InfoBarIconBackgroundGlyph}\"\n                                                    Visibility=\"{x:Bind ShowBadgeOnPluginSettingError}\" />\n                                                <FontIcon\n                                                    FontFamily=\"{StaticResource SymbolThemeFontFamily}\"\n                                                    Foreground=\"{ThemeResource InfoBarErrorSeverityIconForeground}\"\n                                                    Glyph=\"{StaticResource InfoBarErrorIconGlyph}\"\n                                                    Visibility=\"{x:Bind ShowBadgeOnPluginSettingError}\" />\n                                            </Grid>\n\n                                            <ToggleSwitch\n                                                x:Uid=\"PowerLauncher_EnablePluginToggle\"\n                                                IsEnabled=\"{x:Bind Path=EnabledGpoRuleIsConfigured, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}\"\n                                                IsOn=\"{x:Bind Path=Disabled, Converter={StaticResource BoolNegationConverter}, Mode=TwoWay}\" />\n\n                                        </StackPanel>\n                                        <tkcontrols:SettingsExpander.Items>\n                                            <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_ActionKeyword\" IsEnabled=\"{x:Bind Enabled, Mode=OneWay}\">\n                                                <TextBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" Text=\"{x:Bind ActionKeyword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" />\n                                            </tkcontrols:SettingsCard>\n                                            <tkcontrols:SettingsCard\n                                                Padding=\"0,0,0,0\"\n                                                HorizontalContentAlignment=\"Left\"\n                                                Background=\"{ThemeResource SystemFillColorCriticalBackgroundBrush}\"\n                                                ContentAlignment=\"Vertical\"\n                                                Visibility=\"{x:Bind ShowNotAccessibleWarning, Converter={StaticResource BoolToVisibilityConverter}}\">\n                                                <InfoBar\n                                                    x:Uid=\"Run_NotAccessibleWarning\"\n                                                    Margin=\"3,0,0,0\"\n                                                    Background=\"Transparent\"\n                                                    BorderBrush=\"Transparent\"\n                                                    IsClosable=\"False\"\n                                                    IsOpen=\"True\"\n                                                    IsTabStop=\"{x:Bind ShowNotAccessibleWarning}\"\n                                                    Severity=\"Error\" />\n                                            </tkcontrols:SettingsCard>\n                                            <tkcontrols:SettingsCard ContentAlignment=\"Left\" IsEnabled=\"{x:Bind Enabled, Mode=OneWay}\">\n                                                <CheckBox\n                                                    Margin=\"0,-8,0,0\"\n                                                    AutomationProperties.Name=\"{Binding ElementName=IncludeInGlobalResultTitle, Path=Text}\"\n                                                    IsChecked=\"{x:Bind IsGlobal, Mode=TwoWay}\">\n                                                    <StackPanel Orientation=\"Vertical\">\n                                                        <TextBlock x:Name=\"IncludeInGlobalResultTitle\" x:Uid=\"PowerLauncher_IncludeInGlobalResultTitle\" />\n                                                        <controls:IsEnabledTextBlock\n                                                            x:Uid=\"PowerLauncher_IncludeInGlobalResultDescription\"\n                                                            FontSize=\"{StaticResource SecondaryTextFontSize}\"\n                                                            Foreground=\"{ThemeResource TextFillColorSecondaryBrush}\" />\n                                                    </StackPanel>\n                                                </CheckBox>\n                                            </tkcontrols:SettingsCard>\n                                            <tkcontrols:SettingsCard x:Uid=\"PowerLauncher_PluginWeightBoost\" IsEnabled=\"{x:Bind IsGlobalAndEnabled, Mode=OneWay}\">\n                                                <NumberBox\n                                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                                    LargeChange=\"50\"\n                                                    Maximum=\"1000\"\n                                                    Minimum=\"-1000\"\n                                                    SmallChange=\"10\"\n                                                    SpinButtonPlacementMode=\"Compact\"\n                                                    Value=\"{x:Bind WeightBoost, Mode=TwoWay}\" />\n                                            </tkcontrols:SettingsCard>\n                                            <tkcontrols:SettingsCard\n                                                MinHeight=\"0\"\n                                                HorizontalContentAlignment=\"Stretch\"\n                                                ContentAlignment=\"Vertical\">\n                                                <tkcontrols:SettingsCard.Resources>\n                                                    <Thickness x:Key=\"SettingsCardPadding\">0</Thickness>\n                                                    <Thickness x:Key=\"SettingsExpanderItemPadding\">0,0,0,0</Thickness>\n                                                </tkcontrols:SettingsCard.Resources>\n                                                <ItemsControl\n                                                    Margin=\"0,-6,0,0\"\n                                                    HorizontalAlignment=\"Stretch\"\n                                                    HorizontalContentAlignment=\"Stretch\"\n                                                    IsEnabled=\"{x:Bind Enabled, Mode=OneWay}\"\n                                                    ItemTemplateSelector=\"{StaticResource RunOptionTemplateSelector}\"\n                                                    ItemsSource=\"{x:Bind Path=AdditionalOptions}\" />\n                                            </tkcontrols:SettingsCard>\n                                            <tkcontrols:SettingsCard\n                                                MinHeight=\"0\"\n                                                BorderThickness=\"0\"\n                                                ContentAlignment=\"Right\"\n                                                IsEnabled=\"{x:Bind Enabled, Mode=OneWay}\">\n                                                <StackPanel\n                                                    HorizontalAlignment=\"Right\"\n                                                    Orientation=\"Horizontal\"\n                                                    Spacing=\"4\">\n                                                    <TextBlock Opacity=\"{x:Bind DisabledOpacity}\" Style=\"{ThemeResource SecondaryTextStyle}\">\n                                                        <Run x:Uid=\"PowerLauncher_PluginVersion\" />\n                                                        <Run FontWeight=\"SemiBold\" Text=\"{x:Bind Version}\" />\n                                                    </TextBlock>\n                                                    <TextBlock\n                                                        AutomationProperties.Name=\",\"\n                                                        IsTabStop=\"False\"\n                                                        Opacity=\"{x:Bind DisabledOpacity}\"\n                                                        Style=\"{ThemeResource SecondaryTextStyle}\"\n                                                        Text=\"|\" />\n                                                    <TextBlock Opacity=\"{x:Bind DisabledOpacity}\" Style=\"{ThemeResource SecondaryTextStyle}\">\n                                                        <Run x:Uid=\"PowerLauncher_AuthoredBy\" />\n                                                        <Run FontWeight=\"SemiBold\" Text=\"{x:Bind Author}\" />\n                                                    </TextBlock>\n                                                    <TextBlock\n                                                        AutomationProperties.Name=\",\"\n                                                        IsTabStop=\"False\"\n                                                        Opacity=\"{x:Bind DisabledOpacity}\"\n                                                        Style=\"{ThemeResource SecondaryTextStyle}\"\n                                                        Text=\"|\"\n                                                        Visibility=\"{x:Bind HasValidWebsiteUri, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\" />\n                                                    <HyperlinkButton\n                                                        Margin=\"0\"\n                                                        Padding=\"0\"\n                                                        NavigateUri=\"{x:Bind WebsiteUri}\"\n                                                        Opacity=\"{x:Bind DisabledOpacity}\"\n                                                        Style=\"{StaticResource TextButtonStyle}\"\n                                                        Visibility=\"{x:Bind HasValidWebsiteUri, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}\">\n                                                        <TextBlock\n                                                            x:Uid=\"PowerLauncher_PluginWebsite\"\n                                                            FontWeight=\"SemiBold\"\n                                                            Style=\"{ThemeResource SecondaryLinkTextStyle}\" />\n                                                    </HyperlinkButton>\n                                                </StackPanel>\n                                            </tkcontrols:SettingsCard>\n                                        </tkcontrols:SettingsExpander.Items>\n                                    </tkcontrols:SettingsExpander>\n                                </Grid>\n                            </DataTemplate>\n                        </ItemsRepeater.ItemTemplate>\n                    </ItemsRepeater>\n                </controls:SettingsGroup>\n            </StackPanel>\n\n        </controls:SettingsPageControl.ModuleContent>\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_Run\" Link=\"https://aka.ms/PowerToysOverview_PowerToysRun\" />\n            <controls:PageLink x:Uid=\"Run_FindMorePlugins\" Link=\"https://aka.ms/powerToysRunPlugins\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://github.com/Wox-launcher/Wox/\" Text=\"Wox\" />\n            <controls:PageLink Link=\"https://github.com/betsegaw/windowwalker/\" Text=\"Beta Tadele 的软件 Window Walker\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerOcrPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.PowerOcrPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n\n    <controls:SettingsPageControl x:Uid=\"TextExtractor\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/TextExtractor.png\">\n        <controls:SettingsPageControl.ModuleContent>\n            <StackPanel\n                ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\"\n                Orientation=\"Vertical\"\n                Spacing=\"2\">\n                <InfoBar\n                    x:Uid=\"TextExtractor_UseSnippingToolWarning\"\n                    Margin=\"{x:Bind ViewModel.SnippingToolInfoBarMargin, Mode=OneWay}\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsWin11OrGreater, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsWin11OrGreater, Mode=OneWay}\"\n                    Severity=\"Informational\" />\n                <tkcontrols:SettingsCard\n                    x:Uid=\"TextExtractor_EnableToggleControl_HeaderText\"\n                    HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/TextExtractor.png}\"\n                    IsEnabled=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                    <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsEnabled, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <InfoBar\n                    x:Uid=\"GPO_SettingIsManaged\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    Severity=\"Informational\">\n                    <InfoBar.IconSource>\n                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                    </InfoBar.IconSource>\n                </InfoBar>\n                <InfoBar\n                    x:Uid=\"TextExtractor_SupportedLanguages\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\"\n                    Severity=\"Informational\">\n                    <InfoBar.ActionButton>\n                        <HyperlinkButton x:Uid=\"TextExtractor_SupportedLanguages_Link\" NavigateUri=\"https://aka.ms/PowerToysOverview_TextExtractor#supported-languages\" />\n                    </InfoBar.ActionButton>\n                </InfoBar>\n\n                <controls:SettingsGroup x:Uid=\"Shortcut\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"Activation_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.ActivationShortcut, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"TextExtractor_Languages\">\n                        <ComboBox\n                            x:Name=\"TextExtractor_ComboBox\"\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            DropDownOpened=\"TextExtractor_ComboBox_DropDownOpened\"\n                            ItemsSource=\"{x:Bind Path=ViewModel.AvailableLanguages, Mode=OneWay}\"\n                            Loaded=\"TextExtractor_ComboBox_Loaded\"\n                            SelectedIndex=\"{x:Bind Path=ViewModel.LanguageIndex, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n            </StackPanel>\n        </controls:SettingsPageControl.ModuleContent>\n\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_TextExtractor\" Link=\"https://aka.ms/PowerToysOverview_TextExtractor\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://github.com/TheJoeFin/Text-Grab\" Text=\"Based upon Joseph Finney 的软件 Text Grab\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerPreviewPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.PowerPreviewPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n\n    <controls:SettingsPageControl x:Uid=\"FileExplorerPreview\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/FileExplorerPreview.png\">\n        <controls:SettingsPageControl.ModuleContent>\n            <StackPanel ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\" Orientation=\"Vertical\">\n                <controls:SettingsGroup x:Uid=\"FileExplorerPreview_PreviewPane\">\n                    <InfoBar\n                        x:Uid=\"FileExplorerPreview_PreviewHandlerOutlookIncompatibility\"\n                        IsClosable=\"False\"\n                        IsOpen=\"True\"\n                        IsTabStop=\"True\"\n                        Severity=\"Warning\" />\n\n                    <InfoBar\n                        x:Uid=\"GPO_SomePreviewPanesAreManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.SomePreviewPaneEnabledGposConfigured, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.SomePreviewPaneEnabledGposConfigured, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Preview_SVG\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE91B;}\"\n                        IsEnabled=\"{x:Bind ViewModel.SVGRenderIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.SVGRenderIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.SVGRenderIsEnabled, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"FileExplorerPreview_Preview_SVG_Color_Mode\">\n                                <ComboBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    IsEnabled=\"{x:Bind ViewModel.SVGRenderIsEnabled, Mode=OneWay}\"\n                                    SelectedIndex=\"{x:Bind Path=ViewModel.SVGRenderBackgroundColorMode, Mode=TwoWay}\">\n                                    <ComboBoxItem x:Uid=\"FileExplorerPreview_Preview_SVG_Color_Mode_Default\" />\n                                    <ComboBoxItem x:Uid=\"FileExplorerPreview_Preview_SVG_Color_Solid_Color\" />\n                                    <ComboBoxItem x:Uid=\"FileExplorerPreview_Preview_SVG_Checkered_Shade\" />\n                                </ComboBox>\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"FileExplorerPreview_Preview_SVG_Background_Color\" Visibility=\"{x:Bind ViewModel.IsSvgBackgroundColorVisible, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}\">\n                                <controls:ColorPickerButton IsEnabled=\"{x:Bind ViewModel.SVGRenderIsEnabled, Mode=OneWay}\" SelectedColor=\"{x:Bind Path=ViewModel.SVGRenderBackgroundSolidColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_Mode\" Visibility=\"{x:Bind ViewModel.IsSvgCheckeredShadeVisible, Converter={StaticResource BoolToVisibilityConverter}, Mode=OneWay}\">\n                                <ComboBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    IsEnabled=\"{x:Bind ViewModel.SVGRenderIsEnabled, Mode=OneWay}\"\n                                    SelectedIndex=\"{x:Bind Path=ViewModel.SVGRenderBackgroundCheckeredShade, Mode=TwoWay}\">\n                                    <ComboBoxItem x:Uid=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_1\" />\n                                    <ComboBoxItem x:Uid=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_2\" />\n                                    <ComboBoxItem x:Uid=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_3\" />\n                                </ComboBox>\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Preview_Monaco\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE99A;}\"\n                        IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\" IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\">\n                                <CheckBox x:Uid=\"FileExplorerPreview_ToggleSwitch_Monaco_Wrap_Text\" IsChecked=\"{x:Bind ViewModel.MonacoWrapText, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\" IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\">\n                                <controls:CheckBoxWithDescriptionControl\n                                    x:Uid=\"FileExplorerPreview_ToggleSwitch_Monaco_Try_Format\"\n                                    IsChecked=\"{x:Bind ViewModel.MonacoPreviewTryFormat, Mode=TwoWay}\"\n                                    IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"FileExplorerPreview_Toggle_Monaco_Max_File_Size\" IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    Maximum=\"100\"\n                                    Minimum=\"2\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MonacoPreviewMaxFileSize, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"FileExplorerPreview_Toggle_Monaco_Font_Size\" IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    Maximum=\"100\"\n                                    Minimum=\"2\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MonacoPreviewFontSize, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\" IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\">\n                                <CheckBox\n                                    x:Uid=\"FileExplorerPreview_ToggleSwitch_Monaco_Sticky_Scroll\"\n                                    IsChecked=\"{x:Bind ViewModel.MonacoPreviewStickyScroll, Mode=TwoWay}\"\n                                    IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\" IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\">\n                                <CheckBox\n                                    x:Uid=\"FileExplorerPreview_ToggleSwitch_Monaco_Minimap\"\n                                    IsChecked=\"{x:Bind ViewModel.MonacoPreviewMinimap, Mode=TwoWay}\"\n                                    IsEnabled=\"{x:Bind ViewModel.MonacoRenderIsEnabled, Mode=OneWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Preview_MD\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE943;}\"\n                        IsEnabled=\"{x:Bind ViewModel.MDRenderIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.MDRenderIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.MDRenderIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Preview_PDF\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEA90;}\"\n                        IsEnabled=\"{x:Bind ViewModel.PDFRenderIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.PDFRenderIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.PDFRenderIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Preview_GCODE\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE914;}\"\n                        IsEnabled=\"{x:Bind ViewModel.GCODERenderIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.GCODERenderIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.GCODERenderIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Preview_QOI\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE914;}\"\n                        IsEnabled=\"{x:Bind ViewModel.QOIRenderIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.QOIRenderIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.QOIRenderIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"FileExplorerPreview_IconThumbnail_GroupSettings\">\n                    <InfoBar\n                        x:Uid=\"FileExplorerPreview_RebootRequired\"\n                        IsClosable=\"False\"\n                        IsOpen=\"True\"\n                        IsTabStop=\"True\"\n                        Severity=\"Informational\" />\n                    <InfoBar\n                        x:Uid=\"FileExplorerPreview_ThumbnailsMightNotAppearOnRemoteFolders\"\n                        IsClosable=\"False\"\n                        IsOpen=\"True\"\n                        IsTabStop=\"True\"\n                        Severity=\"Warning\" />\n                    <InfoBar\n                        x:Uid=\"GPO_SomeThumbnailProvidersAreManaged\"\n                        IsClosable=\"False\"\n                        IsOpen=\"{x:Bind ViewModel.SomeThumbnailEnabledGposConfigured, Mode=OneWay}\"\n                        IsTabStop=\"{x:Bind ViewModel.SomeThumbnailEnabledGposConfigured, Mode=OneWay}\"\n                        Severity=\"Informational\">\n                        <InfoBar.IconSource>\n                            <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                        </InfoBar.IconSource>\n                    </InfoBar>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Thumbnail_SVG\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE91B;}\"\n                        IsEnabled=\"{x:Bind ViewModel.SVGThumbnailIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.SVGThumbnailIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.SVGThumbnailIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Thumbnail_PDF\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xEA90;}\"\n                        IsEnabled=\"{x:Bind ViewModel.PDFThumbnailIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.PDFThumbnailIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.PDFThumbnailIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Thumbnail_GCODE\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE914;}\"\n                        IsEnabled=\"{x:Bind ViewModel.GCODEThumbnailIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.GCODEThumbnailIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.GCODEThumbnailIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsCard\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Thumbnail_QOI\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE914;}\"\n                        IsEnabled=\"{x:Bind ViewModel.QOIThumbnailIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.QOIThumbnailIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.QOIThumbnailIsEnabled, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsExpander\n                        x:Uid=\"FileExplorerPreview_ToggleSwitch_Thumbnail_STL\"\n                        HeaderIcon=\"{ui:FontIcon Glyph=&#xE914;}\"\n                        IsEnabled=\"{x:Bind ViewModel.STLThumbnailIsGpoDisabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                        <ToggleSwitch\n                            x:Uid=\"ToggleSwitch\"\n                            IsEnabled=\"{x:Bind ViewModel.STLThumbnailIsGpoEnabled, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\"\n                            IsOn=\"{x:Bind ViewModel.STLThumbnailIsEnabled, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"FileExplorerPreview_Color_Thumbnail_STL\">\n                                <controls:ColorPickerButton IsEnabled=\"{x:Bind ViewModel.STLThumbnailIsEnabled, Mode=OneWay}\" SelectedColor=\"{x:Bind Path=ViewModel.STLThumbnailColor, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                </controls:SettingsGroup>\n            </StackPanel>\n        </controls:SettingsPageControl.ModuleContent>\n\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_PowerPreview\" Link=\"https://aka.ms/PowerToysOverview_FileExplorerAddOns\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://blog.aaron-junker.ch\" Text=\"Aaron Junker 开发了程序代码预览功能\" />\n            <controls:PageLink Link=\"https://www.pedrolamas.com\" Text=\"Pedro Lamas 开发了 G-Code、STL、QOI 预览功能\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/PowerRenamePage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.PowerRenamePage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n\n    <controls:SettingsPageControl x:Uid=\"PowerRename\" ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/PowerRename.png\">\n        <controls:SettingsPageControl.ModuleContent>\n            <StackPanel\n                x:Name=\"PowerRenameView\"\n                ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\"\n                Orientation=\"Vertical\">\n                <tkcontrols:SettingsCard\n                    x:Uid=\"PowerRename_Toggle_Enable\"\n                    HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/PowerRename.png}\"\n                    IsEnabled=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                    <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsEnabled, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <InfoBar\n                    x:Uid=\"GPO_SettingIsManaged\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    Severity=\"Informational\">\n                    <InfoBar.IconSource>\n                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                    </InfoBar.IconSource>\n                </InfoBar>\n                <controls:SettingsGroup x:Uid=\"PowerRename_ShellIntegration\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsExpander x:Uid=\"PowerRename_Toggle_ContextMenu\" IsExpanded=\"False\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind ViewModel.EnabledOnContextExtendedMenu, Mode=TwoWay, Converter={StaticResource BoolToComboBoxIndexConverter}}\">\n                            <ComboBoxItem x:Uid=\"PowerRename_Toggle_StandardContextMenu\" />\n                            <ComboBoxItem x:Uid=\"PowerRename_Toggle_ExtendedContextMenu\" />\n                        </ComboBox>\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard ContentAlignment=\"Left\">\n                                <CheckBox x:Uid=\"PowerRename_Toggle_HideIcon\" IsChecked=\"{x:Bind ViewModel.EnabledOnContextMenu, Mode=TwoWay, Converter={StaticResource BoolNegationConverter}}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                    <InfoBar\n                        x:Uid=\"ExtendedContextMenuInfo\"\n                        IsClosable=\"False\"\n                        IsOpen=\"True\"\n                        IsTabStop=\"True\"\n                        Severity=\"Informational\" />\n                </controls:SettingsGroup>\n\n                <controls:SettingsGroup x:Uid=\"PowerRename_AutoCompleteHeader\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsExpander x:Uid=\"PowerRename_Toggle_AutoComplete\" IsExpanded=\"True\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.MRUEnabled, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"PowerRename_Toggle_MaxDispListNum\" IsEnabled=\"{x:Bind ViewModel.GlobalAndMruEnabled, Mode=OneWay}\">\n                                <NumberBox\n                                    MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                                    Maximum=\"20\"\n                                    Minimum=\"0\"\n                                    SpinButtonPlacementMode=\"Compact\"\n                                    Value=\"{x:Bind ViewModel.MaxDispListNum, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n\n                    <tkcontrols:SettingsCard x:Uid=\"PowerRename_Toggle_RestoreFlagsOnLaunch\" HeaderIcon=\"{ui:FontIcon Glyph=&#xe81c;}\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.RestoreFlagsOnLaunch, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"PowerRename_BehaviorHeader\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"PowerRename_Toggle_UseBoostLib\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.UseBoostLib, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n            </StackPanel>\n        </controls:SettingsPageControl.ModuleContent>\n\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_PowerRename\" Link=\"https://aka.ms/PowerToysOverview_PowerRename\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://github.com/chrdavis/SmartRename\" Text=\"Chris Davis 的软件 SmartRenamer\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/SettingsXAML/Views/ZoomItPage.xaml",
    "content": "﻿<Page\n    x:Class=\"Microsoft.PowerToys.Settings.UI.Views.ZoomItPage\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:controls=\"using:Microsoft.PowerToys.Settings.UI.Controls\"\n    xmlns:converters=\"using:Microsoft.PowerToys.Settings.UI.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:tkcontrols=\"using:CommunityToolkit.WinUI.Controls\"\n    xmlns:ui=\"using:CommunityToolkit.WinUI\"\n    AutomationProperties.LandmarkType=\"Main\"\n    mc:Ignorable=\"d\">\n\n    <Page.Resources>\n        <converters:ZoomItInitialZoomConverter x:Key=\"ZoomItInitialZoomConverter\" />\n        <converters:ZoomItTypeSpeedSliderConverter x:Key=\"ZoomItTypeSpeedSliderConverter\" />\n    </Page.Resources>\n\n    <controls:SettingsPageControl\n        x:Uid=\"ZoomIt\"\n        IsTabStop=\"False\"\n        ModuleImageSource=\"ms-appx:///Assets/Settings/Modules/ZoomIt.png\">\n        <controls:SettingsPageControl.ModuleContent>\n            <StackPanel ChildrenTransitions=\"{StaticResource SettingsCardsAnimations}\" Orientation=\"Vertical\">\n                <InfoBar\n                    x:Uid=\"ZoomIt_SimultaneousStandaloneZoomItWarning\"\n                    Margin=\"0,0,0,25\"\n                    IsClosable=\"False\"\n                    IsOpen=\"True\"\n                    IsTabStop=\"True\"\n                    Severity=\"Warning\" />\n                <tkcontrols:SettingsCard\n                    x:Uid=\"ZoomIt_EnableToggleControl_HeaderText\"\n                    HeaderIcon=\"{ui:BitmapIcon Source=/Assets/Settings/Icons/ZoomIt.png}\"\n                    IsEnabled=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}\">\n                    <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.IsEnabled, Mode=TwoWay}\" />\n                </tkcontrols:SettingsCard>\n                <InfoBar\n                    x:Uid=\"GPO_SettingIsManaged\"\n                    IsClosable=\"False\"\n                    IsOpen=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    IsTabStop=\"{x:Bind ViewModel.IsEnabledGpoConfigured, Mode=OneWay}\"\n                    Severity=\"Informational\">\n                    <InfoBar.IconSource>\n                        <FontIconSource FontFamily=\"{StaticResource SymbolThemeFontFamily}\" Glyph=\"&#xE72E;\" />\n                    </InfoBar.IconSource>\n                </InfoBar>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_BehaviorGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Toggle_ShowTrayIcon\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.ShowTrayIcon, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_ZoomGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Zoom_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.ZoomToggleKey, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Toggle_AnimateZoom\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.AnimateZoom, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Slider_InitialMagnification\">\n                        <Slider\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            Maximum=\"5\"\n                            Minimum=\"0\"\n                            ThumbToolTipValueConverter=\"{StaticResource ZoomItInitialZoomConverter}\"\n                            TickFrequency=\"1\"\n                            TickPlacement=\"Outside\"\n                            Value=\"{x:Bind ViewModel.ZoominSliderLevel, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_LiveZoomGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_LiveZoom_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.LiveZoomToggleKey, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_DrawGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Draw_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.DrawToggleKey, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_TypeGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Type_TextFont\">\n                        <tkcontrols:SettingsCard.Description>\n                            <TextBlock\n                                FontFamily=\"{x:Bind ViewModel.DemoSampleFontFamily, Mode=OneWay}\"\n                                FontSize=\"{x:Bind ViewModel.DemoSampleFontSize, Mode=OneWay}\"\n                                FontStyle=\"{x:Bind ViewModel.DemoSampleFontStyle, Mode=OneWay}\"\n                                FontWeight=\"{x:Bind ViewModel.DemoSampleFontWeight, Mode=OneWay}\"\n                                Text=\"Sample\"\n                                TextDecorations=\"{x:Bind ViewModel.DemoSampleTextDecoration, Mode=OneWay}\" />\n                        </tkcontrols:SettingsCard.Description>\n                        <Button x:Uid=\"ZoomIt_Type_Font_Button\" Command=\"{x:Bind ViewModel.SelectTypeFontCommand, Mode=OneWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_DemoTypeGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_DemoType_File\" Description=\"{x:Bind ViewModel.DemoTypeFile, Mode=OneWay}\">\n                        <Button x:Uid=\"ZoomIt_DemoType_File_BrowseButton\" Command=\"{x:Bind ViewModel.SelectDemoTypeFileCommand, Mode=OneWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_DemoType_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.DemoTypeToggleKey, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_DemoType_Toggle_UserDrivenMode\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.DemoTypeUserDrivenMode, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_DemoType_SpeedSlider\" Description=\"{x:Bind ViewModel.DemoTypeSpeedSlider, Mode=OneWay}\">\n                        <Slider\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            Maximum=\"{x:Bind ViewModel.DemoTypeMinTypingSpeed, Mode=OneWay}\"\n                            Minimum=\"{x:Bind ViewModel.DemoTypeMaxTypingSpeed, Mode=OneWay}\"\n                            ThumbToolTipValueConverter=\"{StaticResource ZoomItTypeSpeedSliderConverter}\"\n                            Value=\"{x:Bind ViewModel.DemoTypeSpeedSlider, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_BreakGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Break_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.BreakTimerKey, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Break_Timeout\">\n                        <NumberBox\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            LargeChange=\"10\"\n                            Maximum=\"99\"\n                            Minimum=\"1\"\n                            SmallChange=\"1\"\n                            SpinButtonPlacementMode=\"Compact\"\n                            Value=\"{x:Bind ViewModel.BreakTimeout, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Break_ShowExpiredTime\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.BreakShowExpiredTime, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n\n                    <tkcontrols:SettingsExpander x:Uid=\"ZoomIt_Break_PlaySoundsFile\" IsExpanded=\"True\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.BreakPlaySoundFile, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard\n                                x:Uid=\"ZoomIt_Break_SoundFile\"\n                                Description=\"{x:Bind ViewModel.BreakSoundFile, Mode=OneWay}\"\n                                IsEnabled=\"{x:Bind ViewModel.BreakPlaySoundFile, Mode=OneWay}\">\n                                <Button x:Uid=\"ZoomIt_Break_SoundFile_BrowseButton\" Command=\"{x:Bind ViewModel.SelectBreakSoundFileCommand, Mode=OneWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Break_TimerOpacity\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind Path=ViewModel.BreakTimerOpacityIndex, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_10Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_20Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_30Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_40Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_50Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_60Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_70Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_80Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_90Percent\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerOpacity_100Percent\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Break_TimerPosition\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind Path=ViewModel.BreakTimerPosition, Mode=TwoWay}\">\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_TopLeftCorner\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_TopCenter\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_TopRightCorner\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_Left\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_Center\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_Right\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_BottomLeftCorner\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_BottomCenter\" />\n                            <ComboBoxItem x:Uid=\"ZoomIt_Break_TimerPosition_BottomRightCorner\" />\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsExpander x:Uid=\"ZoomIt_Break_ShowBackgroundBitmap\" IsExpanded=\"True\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.BreakShowBackgroundFile, Mode=TwoWay}\" />\n                        <tkcontrols:SettingsExpander.Items>\n                            <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Break_ShowDesktopOrImageFile\" IsEnabled=\"{x:Bind ViewModel.BreakShowBackgroundFile, Mode=OneWay}\">\n                                <RadioButtons SelectedIndex=\"{x:Bind ViewModel.BreakShowDesktopOrImageFileIndex, Mode=TwoWay}\">\n                                    <RadioButton x:Uid=\"ZoomIt_Break_ShowFadedDesktop\" />\n                                    <RadioButton x:Uid=\"ZoomIt_Break_ShowImageFile\" />\n                                </RadioButtons>\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard\n                                x:Uid=\"ZoomIt_Break_BackgroundFile\"\n                                Description=\"{x:Bind ViewModel.BreakBackgroundFile, Mode=OneWay}\"\n                                IsEnabled=\"{x:Bind ViewModel.BreakShowBackgroundFile, Mode=OneWay}\">\n                                <Button x:Uid=\"ZoomIt_Break_BackgroundFile_BrowseButton\" Command=\"{x:Bind ViewModel.SelectBreakBackgroundFileCommand, Mode=OneWay}\" />\n                            </tkcontrols:SettingsCard>\n                            <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Break_BackgroundStretch\" IsEnabled=\"{x:Bind ViewModel.BreakShowBackgroundFile, Mode=OneWay}\">\n                                <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.BreakBackgroundStretch, Mode=TwoWay}\" />\n                            </tkcontrols:SettingsCard>\n                        </tkcontrols:SettingsExpander.Items>\n                    </tkcontrols:SettingsExpander>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_RecordGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Record_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.RecordToggleKey, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Record_Scaling\">\n                        <ComboBox MinWidth=\"{StaticResource SettingActionControlMinWidth}\" SelectedIndex=\"{x:Bind Path=ViewModel.RecordScalingIndex, Mode=TwoWay}\">\n                            <ComboBoxItem>0.1</ComboBoxItem>\n                            <ComboBoxItem>0.2</ComboBoxItem>\n                            <ComboBoxItem>0.3</ComboBoxItem>\n                            <ComboBoxItem>0.4</ComboBoxItem>\n                            <ComboBoxItem>0.5</ComboBoxItem>\n                            <ComboBoxItem>0.6</ComboBoxItem>\n                            <ComboBoxItem>0.7</ComboBoxItem>\n                            <ComboBoxItem>0.8</ComboBoxItem>\n                            <ComboBoxItem>0.9</ComboBoxItem>\n                            <ComboBoxItem>1.0</ComboBoxItem>\n                        </ComboBox>\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Record_CaptureAudio\">\n                        <ToggleSwitch x:Uid=\"ToggleSwitch\" IsOn=\"{x:Bind ViewModel.RecordCaptureAudio, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Record_Microphone\">\n                        <ComboBox\n                            MinWidth=\"{StaticResource SettingActionControlMinWidth}\"\n                            DisplayMemberPath=\"Item2\"\n                            ItemsSource=\"{x:Bind ViewModel.MicrophoneList}\"\n                            SelectedValue=\"{x:Bind Path=ViewModel.RecordMicrophoneDeviceId, Mode=TwoWay}\"\n                            SelectedValuePath=\"Item1\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n                <controls:SettingsGroup x:Uid=\"ZoomIt_SnipGroup\" IsEnabled=\"{x:Bind ViewModel.IsEnabled, Mode=OneWay}\">\n                    <tkcontrols:SettingsCard x:Uid=\"ZoomIt_Snip_Shortcut\" HeaderIcon=\"{ui:FontIcon Glyph=&#xEDA7;}\">\n                        <controls:ShortcutControl MinWidth=\"{StaticResource SettingActionControlMinWidth}\" HotkeySettings=\"{x:Bind Path=ViewModel.SnipToggleKey, Mode=TwoWay}\" />\n                    </tkcontrols:SettingsCard>\n                </controls:SettingsGroup>\n            </StackPanel>\n        </controls:SettingsPageControl.ModuleContent>\n        <controls:SettingsPageControl.PrimaryLinks>\n            <controls:PageLink x:Uid=\"LearnMore_ZoomIt\" Link=\"https://aka.ms/PowerToysOverview_ZoomIt\" />\n        </controls:SettingsPageControl.PrimaryLinks>\n        <controls:SettingsPageControl.SecondaryLinks>\n            <controls:PageLink Link=\"https://learn.microsoft.com/en-us/sysinternals/downloads/zoomit\" Text=\"原软件 Sysinternals Zoomit 作者 Mark Russinovich、Alex Mihaiuc、John Stephens\" />\n        </controls:SettingsPageControl.SecondaryLinks>\n    </controls:SettingsPageControl>\n</Page>\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/Strings/en-us/Resources.resw",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<root>\n  <!-- \n    Microsoft ResX Schema \n    \n    Version 2.0\n    \n    The primary goals of this format is to allow a simple XML format \n    that is mostly human readable. The generation and parsing of the \n    various data types are done through the TypeConverter classes \n    associated with the data types.\n    \n    Example:\n    \n    ... ado.net/XML headers & schema ...\n    <resheader name=\"resmimetype\">text/microsoft-resx</resheader>\n    <resheader name=\"version\">2.0</resheader>\n    <resheader name=\"reader\">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>\n    <resheader name=\"writer\">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>\n    <data name=\"Name1\"><value>this is my long string</value><comment>this is a comment</comment></data>\n    <data name=\"Color1\" type=\"System.Drawing.Color, System.Drawing\">Blue</data>\n    <data name=\"Bitmap1\" mimetype=\"application/x-microsoft.net.object.binary.base64\">\n        <value>[base64 mime encoded serialized .NET Framework object]</value>\n    </data>\n    <data name=\"Icon1\" type=\"System.Drawing.Icon, System.Drawing\" mimetype=\"application/x-microsoft.net.object.bytearray.base64\">\n        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>\n        <comment>This is a comment</comment>\n    </data>\n                \n    There are any number of \"resheader\" rows that contain simple \n    name/value pairs.\n    \n    Each data row contains a name, and value. The row also contains a \n    type or mimetype. Type corresponds to a .NET class that support \n    text/value conversion through the TypeConverter architecture. \n    Classes that don't support this are serialized and stored with the \n    mimetype set.\n    \n    The mimetype is used for serialized objects, and tells the \n    ResXResourceReader how to depersist the object. This is currently not \n    extensible. For a given mimetype the value must be set accordingly:\n    \n    Note - application/x-microsoft.net.object.binary.base64 is the format \n    that the ResXResourceWriter will generate, however the reader can \n    read any of the formats listed below.\n    \n    mimetype: application/x-microsoft.net.object.binary.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter\n            : and then encoded with base64 encoding.\n    \n    mimetype: application/x-microsoft.net.object.soap.base64\n    value   : The object must be serialized with \n            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter\n            : and then encoded with base64 encoding.\n\n    mimetype: application/x-microsoft.net.object.bytearray.base64\n    value   : The object must be serialized into a byte array \n            : using a System.ComponentModel.TypeConverter\n            : and then encoded with base64 encoding.\n    -->\n  <xsd:schema id=\"root\" xmlns=\"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:msdata=\"urn:schemas-microsoft-com:xml-msdata\">\n    <xsd:import namespace=\"http://www.w3.org/XML/1998/namespace\" />\n    <xsd:element name=\"root\" msdata:IsDataSet=\"true\">\n      <xsd:complexType>\n        <xsd:choice maxOccurs=\"unbounded\">\n          <xsd:element name=\"metadata\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" use=\"required\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"assembly\">\n            <xsd:complexType>\n              <xsd:attribute name=\"alias\" type=\"xsd:string\" />\n              <xsd:attribute name=\"name\" type=\"xsd:string\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"data\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n                <xsd:element name=\"comment\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"2\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" msdata:Ordinal=\"1\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" msdata:Ordinal=\"3\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" msdata:Ordinal=\"4\" />\n              <xsd:attribute ref=\"xml:space\" />\n            </xsd:complexType>\n          </xsd:element>\n          <xsd:element name=\"resheader\">\n            <xsd:complexType>\n              <xsd:sequence>\n                <xsd:element name=\"value\" type=\"xsd:string\" minOccurs=\"0\" msdata:Ordinal=\"1\" />\n              </xsd:sequence>\n              <xsd:attribute name=\"name\" type=\"xsd:string\" use=\"required\" />\n            </xsd:complexType>\n          </xsd:element>\n        </xsd:choice>\n      </xsd:complexType>\n    </xsd:element>\n  </xsd:schema>\n  <resheader name=\"resmimetype\">\n    <value>text/microsoft-resx</value>\n  </resheader>\n  <resheader name=\"version\">\n    <value>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <data name=\"Attribution_Rooler.Text\" xml:space=\"preserve\">\n    <value>灵感来自软件 Rooler</value>\n    <comment>Rooler is a name of the tool.</comment>\n  </data>\n  <data name=\"Shell_MeasureTool.Content\" xml:space=\"preserve\">\n    <value>屏幕标尺</value>\n    <comment>Product name: Navigation view item name for Screen Ruler</comment>\n  </data>\n  <data name=\"MeasureTool.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"MeasureTool.ModuleDescription\" xml:space=\"preserve\">\n    <value>用于像素测量，帮助设计师分析布局。</value>\n    <comment>\"Screen Ruler\" is the name of the utility</comment>\n  </data>\n  <data name=\"MeasureTool.ModuleTitle\" xml:space=\"preserve\">\n    <value>屏幕标尺</value>\n    <comment>\"Screen Ruler\" is the name of the utility</comment>\n  </data>\n  <data name=\"MeasureTool_ActivationSettings.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"MeasureTool_Settings.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n    <comment>\"Screen Ruler\" is the name of the utility</comment>\n  </data>\n  <data name=\"MeasureTool_ActivationShortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"MeasureTool_ActivationShortcut.Description\" xml:space=\"preserve\">\n    <value>打开标尺栏的快捷键</value>\n    <comment>\"Screen Ruler\" is the name of the utility</comment>\n  </data>\n  <data name=\"MeasureTool_DefaultMeasureStyle.Header\" xml:space=\"preserve\">\n    <value>默认测量方法</value>\n  </data>\n  <data name=\"MeasureTool_DefaultMeasureStyle.Description\" xml:space=\"preserve\">\n    <value>打开标尺栏时自动开启的测量功能</value>\n  </data>\n  <data name=\"MeasureTool_DefaultMeasureStyle_None.Content\" xml:space=\"preserve\">\n    <value>无</value>\n  </data>\n  <data name=\"MeasureTool_DefaultMeasureStyle_Bounds.Content\" xml:space=\"preserve\">\n    <value>框选</value>\n  </data>\n  <data name=\"MeasureTool_DefaultMeasureStyle_Spacing.Content\" xml:space=\"preserve\">\n    <value>间距</value>\n  </data>\n  <data name=\"MeasureTool_DefaultMeasureStyle_Horizontal_Spacing.Content\" xml:space=\"preserve\">\n    <value>水平间距</value>\n  </data>\n  <data name=\"MeasureTool_DefaultMeasureStyle_Vertical_Spacing.Content\" xml:space=\"preserve\">\n    <value>垂直间距</value>\n  </data>\n  <data name=\"MeasureTool_UnitsOfMeasure.Header\" xml:space=\"preserve\">\n    <value>额外测量单位</value>\n  </data>\n  <data name=\"MeasureTool_UnitsOfMeasure_Pixels.Content\" xml:space=\"preserve\">\n    <value>仅显示像素</value>\n  </data>\n  <data name=\"MeasureTool_UnitsOfMeasure_Inches.Content\" xml:space=\"preserve\">\n    <value>英寸</value>\n  </data>\n  <data name=\"MeasureTool_UnitsOfMeasure_Centimeters.Content\" xml:space=\"preserve\">\n    <value>厘米</value>\n  </data>\n  <data name=\"MeasureTool_UnitsOfMeasure_Millimeters.Content\" xml:space=\"preserve\">\n    <value>毫米</value>\n  </data>\n  <data name=\"MeasureTool_PixelTolerance.Header\" xml:space=\"preserve\">\n    <value>边缘像素检测容差</value>\n  </data>\n  <data name=\"MeasureTool_MeasureCrossColor.Header\" xml:space=\"preserve\">\n    <value>线条颜色</value>\n  </data>\n  <data name=\"MeasureTool_ContinuousCapture.Header\" xml:space=\"preserve\">\n    <value>实时测量</value>\n  </data>\n  <data name=\"MeasureTool_ContinuousCapture.Description\" xml:space=\"preserve\">\n    <value>每一帧都重新测量，而非冻结屏幕</value>\n  </data>\n  <data name=\"MeasureTool_PerColorChannelEdgeDetection.Header\" xml:space=\"preserve\">\n    <value>通道检测</value>\n  </data>\n  <data name=\"MeasureTool_PerColorChannelEdgeDetection.Description\" xml:space=\"preserve\">\n    <value>检测每个颜色通道的色差，关闭该功能则是检测色差总和</value>\n  </data>\n  <data name=\"MeasureTool_DrawFeetOnCross.Header\" xml:space=\"preserve\">\n    <value>显示线脚</value>\n  </data>\n  <data name=\"MeasureTool_DrawFeetOnCross.Description\" xml:space=\"preserve\">\n    <value>在测量线末端加一条短横线</value>\n  </data>\n  <data name=\"MeasureTool_EnableMeasureTool.Header\" xml:space=\"preserve\">\n    <value>启用屏幕标尺</value>\n    <comment>\"Screen Ruler\" is the name of the utility</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_ActivationSettings.Header\" xml:space=\"preserve\">\n    <value>启用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_DeviceLayoutSettings.Header\" xml:space=\"preserve\">\n    <value>布局</value>\n  </data>\n  <data name=\"MouseWithoutBorders_DeviceLayoutSettings.Description\" xml:space=\"preserve\">\n    <value>拖动可以排序</value>\n  </data>\n  <data name=\"MouseWithoutBorders_CannotDragDropAsAdmin.Title\" xml:space=\"preserve\">\n    <value>管理员权限下不支持拖动，如果需要编辑布局，你可以关闭“始终以管理员身份运行”，然后退出并重新打开 PowerToys</value>\n  </data>\n  <data name=\"MouseWithoutBorders_KeySettings.Header\" xml:space=\"preserve\">\n    <value>连接</value>\n  </data>\n  <data name=\"MouseWithoutBorders_SecurityKey.Header\" xml:space=\"preserve\">\n    <value>连接密码</value>\n  </data>\n  <data name=\"MouseWithoutBorders_SecurityKey.Description\" xml:space=\"preserve\">\n    <value>点击按钮自动生成密码，然后输入到另一台电脑上建立连接，重新生成密码会删除所有已连接设备</value>\n  </data>\n  <data name=\"MouseWithoutBorders_NewKey.Content\" xml:space=\"preserve\">\n    <value>生成</value>\n  </data>\n  <data name=\"MouseWithoutBorders_CopyMachineName.Text\" xml:space=\"preserve\">\n    <value>复制</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ReconnectButton.Text\" xml:space=\"preserve\">\n    <value>刷新连接</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ReconnectTooltip.Text\" xml:space=\"preserve\">\n    <value>如果遇到问题，可以尝试刷新来重新连接其他设备</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ThisMachineNameLabel.Header\" xml:space=\"preserve\">\n    <value>本机名称</value>\n  </data>\n  <data name=\"MouseWithoutBorders_Connect.Content\" xml:space=\"preserve\">\n    <value>连接</value>\n  </data>\n  <data name=\"MouseWithoutBorders_UninstallService.Header\" xml:space=\"preserve\">\n    <value>卸载服务</value>\n  </data>\n  <data name=\"MouseWithoutBorders_UninstallService.Description\" xml:space=\"preserve\">\n    <value>从电脑上卸载此服务，需要管理员权限</value>\n  </data>\n  <data name=\"MouseWithoutBorders_Settings.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"MouseWithoutBorders_TroubleShooting.Header\" xml:space=\"preserve\">\n    <value>修复</value>\n  </data>\n  <data name=\"MouseWithoutBorders_AddFirewallRuleButtonControl.Header\" xml:space=\"preserve\">\n    <value>添加防火墙允许入站规则</value>\n    <comment>\"Mouse Without Borders\" is a product name</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_AddFirewallRuleButtonControl.Description\" xml:space=\"preserve\">\n    <value>点击执行，也许可以修复不能连接的问题</value>\n  </data>\n  <data name=\"MouseWithoutBorders_RunAsAdminText.Title\" xml:space=\"preserve\">\n    <value>要更改此设置，请以管理员身份重新启动软件</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ServiceUserUninstallWarning.Title\" xml:space=\"preserve\">\n    <value>如果以单用户模式安装 PowerToys，升级或者卸载软件后可能需要手动卸载无界鼠标服务</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ServiceSettings.Header\" xml:space=\"preserve\">\n    <value>服务</value>\n  </data>\n  <data name=\"MouseWithoutBorders_Toggle_Enable.Header\" xml:space=\"preserve\">\n    <value>启用无界鼠标</value>\n  </data>\n  <data name=\"MouseWithoutBorders.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"MouseWithoutBorders.ModuleDescription\" xml:space=\"preserve\">\n    <value>一套键鼠控制多台电脑。</value>\n    <comment>\"Mouse Without Borders\" is the name of the utility</comment>\n  </data>\n  <data name=\"MouseWithoutBorders.ModuleTitle\" xml:space=\"preserve\">\n    <value>无界鼠标</value>\n    <comment>\"Mouse Without Borders\" is the name of the utility</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_UseService.Header\" xml:space=\"preserve\">\n    <value>启用无界鼠标服务</value>\n  </data>\n  <data name=\"MouseWithoutBorders_UseService.Description\" xml:space=\"preserve\">\n    <value>以服务模式运行，在本电脑上拥有更高的被控权限，电脑锁屏时也可控制，系统和管理员权限的窗口也可控制</value>\n  </data>\n  <data name=\"MouseWithoutBorders_MatrixOneRow.Header\" xml:space=\"preserve\">\n    <value>单行排列</value>\n  </data>\n  <data name=\"MouseWithoutBorders_MatrixOneRow.Description\" xml:space=\"preserve\">\n    <value>排列成一行，如果关掉就是排成 2x2 的阵列，可按电脑摆放方式调整</value>\n  </data>\n  <data name=\"MouseWithoutBorders_WrapMouse.Header\" xml:space=\"preserve\">\n    <value>循环移动</value>\n  </data>\n  <data name=\"MouseWithoutBorders_WrapMouse.Description\" xml:space=\"preserve\">\n    <value>鼠标移动超过最后一台电脑屏幕后，回到第一台电脑上</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ShareClipboard.Header\" xml:space=\"preserve\">\n    <value>共享剪贴板</value>\n  </data>\n  <data name=\"MouseWithoutBorders_TransferFile.Header\" xml:space=\"preserve\">\n    <value>自动传输文件</value>\n  </data>\n  <data name=\"MouseWithoutBorders_HideMouseAtScreenEdge.Header\" xml:space=\"preserve\">\n    <value>移出屏幕隐藏鼠标</value>\n  </data>\n  <data name=\"MouseWithoutBorders_DrawMouseCursor.Header\" xml:space=\"preserve\">\n    <value>绘制鼠标光标</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ValidateRemoteMachineIP.Header\" xml:space=\"preserve\">\n    <value>验证设备地址</value>\n  </data>\n  <data name=\"MouseWithoutBorders_SameSubnetOnly.Header\" xml:space=\"preserve\">\n    <value>仅限内网控制</value>\n  </data>\n  <data name=\"MouseWithoutBorders_BlockScreenSaverOnOtherMachines.Header\" xml:space=\"preserve\">\n    <value>阻止屏保</value>\n  </data>\n  <data name=\"MouseWithoutBorders_MoveMouseRelatively.Header\" xml:space=\"preserve\">\n    <value>鼠标相对移动</value>\n  </data>\n  <data name=\"MouseWithoutBorders_BlockMouseAtScreenCorners.Header\" xml:space=\"preserve\">\n    <value>屏幕四角阻挡</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages.Header\" xml:space=\"preserve\">\n    <value>显示状态通知</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ShowOriginalUI.Header\" xml:space=\"preserve\">\n    <value>显示原版微软无界鼠标界面</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ShowOriginalUI.Description\" xml:space=\"preserve\">\n    <value>需要重开一下无界鼠标功能，然后点击右下角状态栏图标即可打开原版界面</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ShareClipboard.Description\" xml:space=\"preserve\">\n    <value>共享复制的内容，如果功能突然失效，按 Ctrl + Alt + Del 然后按 Esc 也许可以解决问题</value>\n  </data>\n  <data name=\"MouseWithoutBorders_TransferFile.Description\" xml:space=\"preserve\">\n    <value>自动传输复制的文件，大小需小于 100MB（已修改为 500MB）</value>\n  </data>\n  <data name=\"MouseWithoutBorders_HideMouseAtScreenEdge.Description\" xml:space=\"preserve\">\n    <value>鼠标移出屏幕后，把本设备光标隐藏在屏幕顶部，消除当前窗口焦点，使键盘输入转移到被控电脑</value>\n  </data>\n  <data name=\"MouseWithoutBorders_DrawMouseCursor.Description\" xml:space=\"preserve\">\n    <value>在 Win10 以上，如果电脑没插鼠标，那么默认不会显示鼠标光标，需要单独绘制</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ValidateRemoteMachineIP.Description\" xml:space=\"preserve\">\n    <value>通过反向 DNS 查找来验证远程电脑的 IP 地址</value>\n  </data>\n  <data name=\"MouseWithoutBorders_SameSubnetOnly.Description\" xml:space=\"preserve\">\n    <value>仅允许连接到同一内网 NNN.NNN.*.* 下的电脑，只支持 IPv4</value>\n  </data>\n  <data name=\"MouseWithoutBorders_IPAddressMapping_TextBoxControl.PlaceholderText\" xml:space=\"preserve\">\n    <value>例如: MyLaptop 192.168.0.24</value>\n    <comment>Don't translate MyLaptop</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_IPAddressMapping.Header\" xml:space=\"preserve\">\n    <value>IP 地址映射</value>\n  </data>\n  <data name=\"MouseWithoutBorders_IPAddressMapping.Description\" xml:space=\"preserve\">\n    <value>手动设置计算机名称的对应 IP 地址</value>\n  </data>\n  <data name=\"MouseWithoutBorders_BlockScreenSaverOnOtherMachines.Description\" xml:space=\"preserve\">\n    <value>阻止被控电脑启动屏幕保护程序</value>\n  </data>\n  <data name=\"MouseWithoutBorders_MoveMouseRelatively.Description\" xml:space=\"preserve\">\n    <value>提供不同屏幕配置和多屏使用的支持</value>\n  </data>\n  <data name=\"MouseWithoutBorders_BlockMouseAtScreenCorners.Description\" xml:space=\"preserve\">\n    <value>在屏幕四角处阻挡跨界，防止误触</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ShowClipboardAndNetworkStatusMessages.Description\" xml:space=\"preserve\">\n    <value>剪贴板和网络状态发生变化时，发送系统通知</value>\n  </data>\n  <data name=\"MouseWithoutBorders_KeyboardShortcuts_Group.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n    <comment>keyboard is the hardware peripheral</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_AdvancedSettings_Group.Header\" xml:space=\"preserve\">\n    <value>高级</value>\n  </data>\n  <data name=\"MouseWithoutBorders_EasyMouseOption.Header\" xml:space=\"preserve\">\n    <value>易动模式</value>\n  </data>\n  <data name=\"MouseWithoutBorders_EasyMouseOption.Description\" xml:space=\"preserve\">\n    <value>移动鼠标跨过屏幕边缘，直接跨电脑移动</value>\n    <comment>Shift and Ctrl are the keyboard keys</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_EasyMouseOption_Disabled.Content\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_EasyMouseOption_Enabled.Content\" xml:space=\"preserve\">\n    <value>启用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_EasyMouseOption_Ctrl.Content\" xml:space=\"preserve\">\n    <value>按住 Ctrl</value>\n    <comment>This is the Ctrl keyboard key</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_EasyMouseOption_Shift.Content\" xml:space=\"preserve\">\n    <value>按住 Shift</value>\n    <comment>This is the Shift keyboard key</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_LockMachinesShortcut.Header\" xml:space=\"preserve\">\n    <value>全部锁屏</value>\n  </data>\n  <data name=\"MouseWithoutBorders_LockMachinesShortcut.Description\" xml:space=\"preserve\">\n    <value>双击快捷键，锁定所有设置了相同锁屏快捷键的电脑</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ToggleEasyMouseShortcut.Header\" xml:space=\"preserve\">\n    <value>切换易动</value>\n    <comment>Ctrl and Alt are the keyboard keys</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_ToggleEasyMouseShortcut.Description\" xml:space=\"preserve\">\n    <value>切换易动模式的开关，易动设置为按住按键开启时该切换无效</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ToggleEasyMouseShortcut_Disabled.Content\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_SwitchBetweenMachineShortcut.Header\" xml:space=\"preserve\">\n    <value>切换设备</value>\n    <comment>Ctrl and Alt are the keyboard keys</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_SwitchBetweenMachineShortcut.Description\" xml:space=\"preserve\">\n    <value>点击 Ctrl + Alt + 指定按键，切换控制不同电脑</value>\n    <comment>Ctrl and Alt are the keyboard keys</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_SwitchBetweenMachineShortcut_F1.Content\" xml:space=\"preserve\">\n    <value>F1, F2, F3, F4</value>\n    <comment>Don't localize. These are keyboard keys</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_SwitchBetweenMachineShortcut_1.Content\" xml:space=\"preserve\">\n    <value>1, 2, 3, 4</value>\n    <comment>Don't localize. These are keyboard keys</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_SwitchBetweenMachineShortcut_Disabled.Content\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_LockMachinesShortcut_Disabled.Content\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ReconnectShortcut.Header\" xml:space=\"preserve\">\n    <value>刷新连接</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ReconnectShortcut.Description\" xml:space=\"preserve\">\n    <value>重新连接其他电脑</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ReconnectShortcut_Disabled.Content\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_Switch2AllPcShortcut.Header\" xml:space=\"preserve\">\n    <value>同步模式</value>\n  </data>\n  <data name=\"MouseWithoutBorders_Switch2AllPcShortcut.Description\" xml:space=\"preserve\">\n    <value>同时控制所有电脑</value>\n  </data>\n  <data name=\"MouseWithoutBorders_Switch2AllPcShortcut_Disabled.Content\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"MouseWithoutBorders_Switch2AllPcShortcut_Ctrl3.Content\" xml:space=\"preserve\">\n    <value>按三下 Ctrl</value>\n    <comment>This is the Ctrl keyboard key</comment>\n  </data>\n  <data name=\"Shell_General.Content\" xml:space=\"preserve\">\n    <value>常规</value>\n    <comment>Navigation view item name for General</comment>\n  </data>\n  <data name=\"Shell_Awake.Content\" xml:space=\"preserve\">\n    <value>阻止睡眠</value>\n    <comment>Product name: Navigation view item name for Awake</comment>\n  </data>\n  <data name=\"Shell_PowerLauncher.Content\" xml:space=\"preserve\">\n    <value>快捷启动器</value>\n    <comment>Product name: Navigation view item name for PowerToys Run</comment>\n  </data>\n  <data name=\"Shell_PowerRename.Content\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>Product name: Navigation view item name for PowerRename</comment>\n  </data>\n  <data name=\"Shell_ShortcutGuide.Content\" xml:space=\"preserve\">\n    <value>快捷键指南</value>\n    <comment>Product name: Navigation view item name for Shortcut Guide</comment>\n  </data>\n  <data name=\"Shell_PowerPreview.Content\" xml:space=\"preserve\">\n    <value>预览增强</value>\n    <comment>Product name: Navigation view item name for File Explorer.  Please use File Explorer as in the context of File Explorer in Windows</comment>\n  </data>\n  <data name=\"Shell_FancyZones.Content\" xml:space=\"preserve\">\n    <value>窗口布局</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"Shell_ImageResizer.Content\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n    <comment>Product name: Navigation view item name for Image Resizer</comment>\n  </data>\n  <data name=\"Shell_ColorPicker.Content\" xml:space=\"preserve\">\n    <value>取色器</value>\n    <comment>Product name: Navigation view item name for Color Picker</comment>\n  </data>\n  <data name=\"Shell_KeyboardManager.Content\" xml:space=\"preserve\">\n    <value>键盘修改器</value>\n    <comment>Product name: Navigation view item name for Keyboard Manager</comment>\n  </data>\n  <data name=\"Shell_MouseWithoutBorders.Content\" xml:space=\"preserve\">\n    <value>无界鼠标</value>\n    <comment>Product name: Navigation view item name for Mouse Without Borders</comment>\n  </data>\n  <data name=\"Shell_MouseUtilities.Content\" xml:space=\"preserve\">\n    <value>鼠标工具箱</value>\n    <comment>Product name: Navigation view item name for Mouse utilities</comment>\n  </data>\n  <data name=\"Shell_NavigationMenu_Announce_Collapse\" xml:space=\"preserve\">\n    <value>导航栏关闭</value>\n    <comment>Accessibility announcement when the navigation pane collapses</comment>\n  </data>\n  <data name=\"Shell_NavigationMenu_Announce_Open\" xml:space=\"preserve\">\n    <value>导航栏开启</value>\n    <comment>Accessibility announcement when the navigation pane opens</comment>\n  </data>\n  <data name=\"KeyboardManager_ConfigHeader.Text\" xml:space=\"preserve\">\n    <value>当前配置</value>\n    <comment>Keyboard Manager current configuration header</comment>\n  </data>\n  <data name=\"KeyboardManager.ModuleDescription\" xml:space=\"preserve\">\n    <value>修改按键映射，自定义键盘。</value>\n    <comment>Keyboard Manager page description</comment>\n  </data>\n  <data name=\"KeyboardManager_EnableToggle.Header\" xml:space=\"preserve\">\n    <value>启用键盘修改器</value>\n    <comment>Keyboard Manager enable toggle header. Do not loc the Product name. Do you want this feature on / off</comment>\n  </data>\n  <data name=\"KeyboardManager_ProfileDescription.Text\" xml:space=\"preserve\">\n    <value>选择配置文件以显示激活的重映射链</value>\n    <comment>Keyboard Manager configuration dropdown description</comment>\n  </data>\n  <data name=\"KeyboardManager_RemapKeyboardButton.Header\" xml:space=\"preserve\">\n    <value>重映射单键</value>\n    <comment>Keyboard Manager remap keyboard button content</comment>\n  </data>\n  <data name=\"KeyboardManager_Keys.Header\" xml:space=\"preserve\">\n    <value>单键</value>\n    <comment>Keyboard Manager remap keyboard header</comment>\n  </data>\n  <data name=\"KeyboardManager_RemapShortcutsButton.Header\" xml:space=\"preserve\">\n    <value>重映射组合键</value>\n    <comment>Keyboard Manager remap shortcuts button</comment>\n  </data>\n  <data name=\"KeyboardManager_Shortcuts.Header\" xml:space=\"preserve\">\n    <value>组合键</value>\n    <comment>Keyboard Manager remap keyboard header</comment>\n  </data>\n  <data name=\"KeyboardManager_All_Apps_Description\" xml:space=\"preserve\">\n    <value>全局生效</value>\n    <comment>Should be the same as EditShortcuts_AllApps from keyboard manager editor</comment>\n  </data>\n  <data name=\"Shortcuts.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"Shortcut.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIButton.Content\" xml:space=\"preserve\">\n    <value>启用</value>\n  </data>\n  <data name=\"AdvancedPaste_DisableAIButton.Content\" xml:space=\"preserve\">\n    <value>禁用</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAISettingsCard.Header\" xml:space=\"preserve\">\n    <value>启用 AI 粘贴</value>\n  </data>\n  <data name=\"AdvancedPaste_Clipboard_History_Enabled_SettingsCard.Header\" xml:space=\"preserve\">\n    <value>剪贴板历史记录</value>\n  </data>\n  <data name=\"AdvancedPaste_Clipboard_History_Enabled_SettingsCard.Description\" xml:space=\"preserve\">\n    <value>保留复制的历史记录，这是系统自带的功能，按 Win+V 显示</value>\n  </data>\n  <data name=\"AdvancedPaste_Direct_Access_Hotkeys_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>操作</value>\n  </data>\n  <data name=\"AdvancedPaste_Additional_Actions_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>其他操作</value>\n  </data>\n  <data name=\"RemapKeysList.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>当前单键重映射列表</value>\n  </data>\n  <data name=\"RemapShortcutsList.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>当前组合键重映射列表</value>\n  </data>\n  <data name=\"KeyboardManager_RemappedKeysListItem.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>单键重映射列表项</value>\n    <comment>key as in keyboard key</comment>\n  </data>\n  <data name=\"KeyboardManager_RemappedShortcutsListItem.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>组合键重映射列表项</value>\n  </data>\n  <data name=\"KeyboardManager_RemappedTo.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>映射功能</value>\n  </data>\n  <data name=\"KeyboardManager_ShortcutRemappedTo.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>映射功能</value>\n  </data>\n  <data name=\"KeyboardManager_TargetApp.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>程序</value>\n    <comment>What computer application would this be for</comment>\n  </data>\n  <data name=\"KeyboardManager_Image.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>键盘修改器</value>\n    <comment>do not loc, product name</comment>\n  </data>\n  <data name=\"ColorPicker.ModuleDescription\" xml:space=\"preserve\">\n    <value>简单好用的屏幕取色器。</value>\n  </data>\n  <data name=\"ColorPicker_EnableColorPicker.Header\" xml:space=\"preserve\">\n    <value>启用取色器</value>\n    <comment>do not loc the Product name.  Do you want this feature on / off</comment>\n  </data>\n  <data name=\"ColorPicker_ChangeCursor.Content\" xml:space=\"preserve\">\n    <value>取色时改变光标造型</value>\n  </data>\n  <data name=\"PowerLauncher.ModuleDescription\" xml:space=\"preserve\">\n    <value>通过搜索来启动丰富的功能。</value>\n  </data>\n  <data name=\"PowerLauncher_EnablePowerLauncher.Header\" xml:space=\"preserve\">\n    <value>启用快捷启动器</value>\n    <comment>do not loc the Product name.  Do you want this feature on / off</comment>\n  </data>\n  <data name=\"PowerLauncher_SearchResults.Header\" xml:space=\"preserve\">\n    <value>搜索结果</value>\n  </data>\n  <data name=\"PowerLauncher_SearchResultPreference.Header\" xml:space=\"preserve\">\n    <value>搜索结果设置</value>\n  </data>\n  <data name=\"PowerLauncher_UsePinyin.Header\" xml:space=\"preserve\">\n    <value>拼音搜索</value>\n  </data>\n  <data name=\"PowerLauncher_UsePinyin.Description\" xml:space=\"preserve\">\n    <value>支持用拼音搜索，这是实验性的新功能，不一定支持所有插件</value>\n  </data>\n  <data name=\"PowerLauncher_SearchResultPreference_MostRecentlyUsed\" xml:space=\"preserve\">\n    <value>最近使用</value>\n  </data>\n  <data name=\"PowerLauncher_SearchResultPreference_AlphabeticalOrder\" xml:space=\"preserve\">\n    <value>按字母顺序</value>\n  </data>\n  <data name=\"PowerLauncher_SearchResultPreference_RunningProcessesOpenApplications\" xml:space=\"preserve\">\n    <value>运行中的进程／打开的应用</value>\n  </data>\n  <data name=\"PowerLauncher_SearchTypePreference.Header\" xml:space=\"preserve\">\n    <value>搜索类型设置</value>\n  </data>\n  <data name=\"PowerLauncher_SearchTypePreference_ApplicationName\" xml:space=\"preserve\">\n    <value>应用名</value>\n  </data>\n  <data name=\"PowerLauncher_SearchTypePreference_StringInApplication\" xml:space=\"preserve\">\n    <value>应用程序中包含的文字</value>\n  </data>\n  <data name=\"PowerLauncher_SearchTypePreference_ExecutableName\" xml:space=\"preserve\">\n    <value>可执行文件名</value>\n  </data>\n  <data name=\"PowerLauncher_MaximumNumberOfResults.Header\" xml:space=\"preserve\">\n    <value>每页显示结果数</value>\n  </data>\n  <data name=\"PowerLauncher_OpenPowerLauncher.Header\" xml:space=\"preserve\">\n    <value>启动快捷启动器</value>\n  </data>\n  <data name=\"PowerLauncher_OpenFileLocation.Header\" xml:space=\"preserve\">\n    <value>打开所在文件夹</value>\n  </data>\n  <data name=\"PowerLauncher_CopyPathLocation.Header\" xml:space=\"preserve\">\n    <value>复制文件路径</value>\n  </data>\n  <data name=\"PowerLauncher_OpenConsole.Header\" xml:space=\"preserve\">\n    <value>打开命令行</value>\n    <comment>console refers to Windows command prompt</comment>\n  </data>\n  <data name=\"PowerLauncher_OverrideWinRKey.Content\" xml:space=\"preserve\">\n    <value>代替 Win+R</value>\n  </data>\n  <data name=\"PowerLauncher_OverrideWinSKey.Content\" xml:space=\"preserve\">\n    <value>代替 Win+S</value>\n  </data>\n  <data name=\"PowerLauncher_IgnoreHotkeysInFullScreen.Content\" xml:space=\"preserve\">\n    <value>全屏时不响应快捷键</value>\n  </data>\n  <data name=\"PowerLauncher_UseCentralizedKeyboardHook.Header\" xml:space=\"preserve\">\n    <value>使用独立的快捷键侦听器</value>\n  </data>\n  <data name=\"PowerLauncher_UseCentralizedKeyboardHook.Description\" xml:space=\"preserve\">\n    <value>全局快捷键失效的备用方案（从管理员权限窗口唤起时启动器可能得不到焦点）</value>\n  </data>\n  <data name=\"PowerLauncher_ClearInputOnLaunch.Content\" xml:space=\"preserve\">\n    <value>启动时清空上次搜索</value>\n  </data>\n  <data name=\"PowerLauncher_TabSelectsContextButtons.Header\" xml:space=\"preserve\">\n    <value>按 Tab 键选中具体操作</value>\n  </data>\n  <data name=\"PowerLauncher_TabSelectsContextButtons.Description\" xml:space=\"preserve\">\n    <value>按 Tab 键可选中当前结果项的各个操作按钮，直到跳转下一项</value>\n  </data>\n  <data name=\"PowerLauncher_GenerateThumbnailsFromFiles.Header\" xml:space=\"preserve\">\n    <value>显示文件缩略图</value>\n  </data>\n  <data name=\"PowerLauncher_GenerateThumbnailsFromFiles.Description\" xml:space=\"preserve\">\n    <value>关掉可以加快加载速度、提高稳定性</value>\n  </data>\n  <data name=\"PowerLauncher_SearchQueryResultsWithDelay.Header\" xml:space=\"preserve\">\n    <value>输入缓冲</value>\n    <comment>This is about adding a delay to wait for more input before executing a search</comment>\n  </data>\n  <data name=\"PowerLauncher_SearchQueryResultsWithDelay.Description\" xml:space=\"preserve\">\n    <value>等待输入结束后再开始搜索，减少系统开销</value>\n  </data>\n  <data name=\"PowerLauncher_FastSearchInputDelayMs.Header\" xml:space=\"preserve\">\n    <value>即时显示缓冲</value>\n  </data>\n  <data name=\"PowerLauncher_FastSearchInputDelayMs.Description\" xml:space=\"preserve\">\n    <value>对于立刻显示结果的插件，推荐缓冲 30-50 毫秒</value>\n  </data>\n  <data name=\"PowerLauncher_SlowSearchInputDelayMs.Header\" xml:space=\"preserve\">\n    <value>后台运算缓冲</value>\n  </data>\n  <data name=\"PowerLauncher_SlowSearchInputDelayMs.Description\" xml:space=\"preserve\">\n    <value>对于运算结束再呈现结果的插件，推荐缓冲 100-150 毫秒</value>\n  </data>\n  <data name=\"PowerLauncher_SearchInputDelayMs.Header\" xml:space=\"preserve\">\n    <value>缓冲时间（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"KeyboardManager_KeysMappingLayoutRightHeader.Text\" xml:space=\"preserve\">\n    <value>目标</value>\n    <comment>Keyboard Manager mapping keys view right header</comment>\n  </data>\n  <data name=\"Appearance_GroupSettings.Text\" xml:space=\"preserve\">\n    <value>外观</value>\n  </data>\n  <data name=\"Fancyzones_ImageHyperlinkToDocs.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>布局窗口</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"FancyZones.ModuleDescription\" xml:space=\"preserve\">\n    <value>创建窗口布局，便于多任务处理。</value>\n    <comment>windows refers to application windows</comment>\n  </data>\n  <data name=\"FancyZones_DisplayOrWorkAreaChangeMoveWindowsCheckBoxControl.Content\" xml:space=\"preserve\">\n    <value>当屏幕分辨率或工作区变化时，自动调整窗口以维持布局</value>\n    <comment>windows refers to application windows</comment>\n  </data>\n  <data name=\"FancyZones_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用窗口布局</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"FancyZones_ExcludeApps.Header\" xml:space=\"preserve\">\n    <value>忽略应用列表</value>\n  </data>\n  <data name=\"FancyZones_ExcludeApps.Description\" xml:space=\"preserve\">\n    <value>填写忽略应用的名称，每行一个，这些应用程序不受到布局管理</value>\n  </data>\n  <data name=\"FancyZones_HighlightOpacity.Header\" xml:space=\"preserve\">\n    <value>不透明度（%）</value>\n  </data>\n  <data name=\"FancyZones_HotkeyEditorControl.Header\" xml:space=\"preserve\">\n    <value>启动布局编辑器</value>\n    <comment>Shortcut to launch the FancyZones layout editor application</comment>\n  </data>\n  <data name=\"FancyZones_WindowSwitching_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>快捷窗口切换</value>\n  </data>\n  <data name=\"FancyZones_HotkeyNextTabControl.Header\" xml:space=\"preserve\">\n    <value>下一个窗口</value>\n  </data>\n  <data name=\"FancyZones_HotkeyPrevTabControl.Header\" xml:space=\"preserve\">\n    <value>上一个窗口</value>\n  </data>\n  <data name=\"SettingsPage_SetShortcut.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>快捷键设置</value>\n  </data>\n  <data name=\"SettingsPage_SetShortcut_Glyph.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>信息符号</value>\n  </data>\n  <data name=\"FancyZones_LaunchEditorButtonControl.Header\" xml:space=\"preserve\">\n    <value>启动布局编辑器</value>\n    <comment>launches the FancyZones layout editor application</comment>\n  </data>\n  <data name=\"FancyZones_LaunchEditorButtonControl.Description\" xml:space=\"preserve\">\n    <value>配置和管理窗口布局</value>\n    <comment>launches the FancyZones layout editor application</comment>\n  </data>\n  <data name=\"FancyZones_MakeDraggedWindowTransparentCheckBoxControl.Content\" xml:space=\"preserve\">\n    <value>拖动窗口时，使窗口半透明</value>\n  </data>\n  <data name=\"FancyZones_MouseDragCheckBoxControl_Header.Content\" xml:space=\"preserve\">\n    <value>左键拖动窗口，用其他鼠标键激活布局</value>\n  </data>\n  <data name=\"FancyZones_MouseMiddleClickSpanningMultipleZonesCheckBoxControl_Header.Content\" xml:space=\"preserve\">\n    <value>中键切换窗口跨区开关</value>\n  </data>\n  <data name=\"FancyZones_MoveWindowsAcrossAllMonitorsCheckBoxControl.Content\" xml:space=\"preserve\">\n    <value>跨显示器循环移动</value>\n  </data>\n  <data name=\"FancyZones_OverrideSnapHotkeys.Header\" xml:space=\"preserve\">\n    <value>代替系统窗口贴靠</value>\n  </data>\n  <data name=\"FancyZones_OverrideSnapHotkeys.Description\" xml:space=\"preserve\">\n    <value>替换系统快捷键（Win + 方向键）用于在布局中移动窗口</value>\n  </data>\n  <data name=\"FancyZones_ShiftDragCheckBoxControl_Header.Content\" xml:space=\"preserve\">\n    <value>左键拖动窗口，按住 Shift 激活布局</value>\n  </data>\n  <data name=\"FancyZones_ActivationNoShiftDrag\" xml:space=\"preserve\">\n    <value>直接拖动窗口激活布局</value>\n  </data>\n  <data name=\"FancyZones_ShowZonesOnAllMonitorsCheckBoxControl.Content\" xml:space=\"preserve\">\n    <value>拖动窗口时，在所有显示器上都显示布局区</value>\n  </data>\n  <data name=\"FancyZones_AppLastZoneMoveWindows.Content\" xml:space=\"preserve\">\n    <value>将新打开的窗口放入其常用布局</value>\n    <comment>windows refers to application windows</comment>\n  </data>\n  <data name=\"FancyZones_OpenWindowOnActiveMonitor.Content\" xml:space=\"preserve\">\n    <value>将新打开的窗口移至当前活动显示器，实验性功能</value>\n  </data>\n  <data name=\"FancyZones_UseCursorPosEditorStartupScreen.Header\" xml:space=\"preserve\">\n    <value>编辑器启动位置</value>\n  </data>\n  <data name=\"FancyZones_UseCursorPosEditorStartupScreen.Description\" xml:space=\"preserve\">\n    <value>使用多个显示器时在哪个显示器打开</value>\n  </data>\n  <data name=\"FancyZones_LaunchPositionMouse.Content\" xml:space=\"preserve\">\n    <value>鼠标光标所在显示器</value>\n  </data>\n  <data name=\"FancyZones_LaunchPositionScreen.Content\" xml:space=\"preserve\">\n    <value>窗口焦点所在显示器</value>\n  </data>\n  <data name=\"FancyZones_ZoneBehavior_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>布局功能</value>\n  </data>\n  <data name=\"FancyZones_ZoneBehavior_GroupSettings.Description\" xml:space=\"preserve\">\n    <value>管理布局的功能</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"FancyZones_Zones.Header\" xml:space=\"preserve\">\n    <value>布局</value>\n  </data>\n  <data name=\"FancyZones_ZoneHighlightColor.Header\" xml:space=\"preserve\">\n    <value>激活颜色</value>\n  </data>\n  <data name=\"FancyZones_ZoneSetChangeMoveWindows.Content\" xml:space=\"preserve\">\n    <value>布局切换时，自动调整窗口适配新的布局</value>\n  </data>\n  <data name=\"AttributionTitle.Text\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"General.ModuleTitle\" xml:space=\"preserve\">\n    <value>常规</value>\n  </data>\n  <data name=\"GeneralPage_CheckForUpdates.Content\" xml:space=\"preserve\">\n    <value>检查更新</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestoreLocationText.Header\" xml:space=\"preserve\">\n    <value>备份位置</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_ButtonBackup.Content\" xml:space=\"preserve\">\n    <value>备份</value>\n  </data>\n  <data name=\"General_SettingsBackupInfo_FileNameHeader.Text\" xml:space=\"preserve\">\n    <value>文件:</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_LinkRefresh.Text\" xml:space=\"preserve\">\n    <value>刷新</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_ButtonRestore.Content\" xml:space=\"preserve\">\n    <value>还原</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_ButtonSelectFolder.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>选择</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_ButtonSelectLocation.Text\" xml:space=\"preserve\">\n    <value>选择</value>\n  </data>\n  <data name=\"GeneralPage_UpdateNow.Content\" xml:space=\"preserve\">\n    <value>立即更新</value>\n  </data>\n  <data name=\"GeneralPage_PrivacyStatement_URL.Text\" xml:space=\"preserve\">\n    <value>隐私声明</value>\n  </data>\n  <data name=\"GeneralPage_ReportAbug.Text\" xml:space=\"preserve\">\n    <value>问题反馈</value>\n    <comment>Report an issue inside powertoys</comment>\n  </data>\n  <data name=\"GeneralPage_RequestAFeature_URL.Text\" xml:space=\"preserve\">\n    <value>功能建议</value>\n    <comment>Tell our team what we should build</comment>\n  </data>\n  <data name=\"GeneralPage_RestartAsAdmin_Button.Content\" xml:space=\"preserve\">\n    <value>以管理员身份重启</value>\n    <comment>running PowerToys as a higher level user, account is typically referred to as an admin / administrator</comment>\n  </data>\n  <data name=\"GeneralPage_RunAtStartUp.Header\" xml:space=\"preserve\">\n    <value>开机自启</value>\n  </data>\n  <data name=\"GeneralPage_RunAtStartUp.Description\" xml:space=\"preserve\">\n    <value>电脑开机时自动运行</value>\n  </data>\n  <data name=\"GeneralPage_WarningsElevatedApps.Content\" xml:space=\"preserve\">\n    <value>遇到管理员权限的软件时显示功能受限警告</value>\n  </data>\n  <data name=\"PowerRename.ModuleDescription\" xml:space=\"preserve\">\n    <value>通过简单的搜索替换来自动化重命名文件。</value>\n  </data>\n  <data name=\"PowerRename_ShellIntegration.Header\" xml:space=\"preserve\">\n    <value>右键菜单集成</value>\n    <comment>This refers to directly integrating in with Windows</comment>\n  </data>\n  <data name=\"PowerRename_Toggle_Enable.Header\" xml:space=\"preserve\">\n    <value>启用批量重命名</value>\n    <comment>do not loc the Product name.  Do you want this feature on / off</comment>\n  </data>\n  <data name=\"RadioButtons_Name_Theme.Text\" xml:space=\"preserve\">\n    <value>主题</value>\n  </data>\n  <data name=\"PowerRename_Toggle_HideIcon.Content\" xml:space=\"preserve\">\n    <value>右键菜单隐藏图标</value>\n  </data>\n  <data name=\"PowerRename_Toggle_ContextMenu.Header\" xml:space=\"preserve\">\n    <value>显示位置</value>\n  </data>\n  <data name=\"PowerRename_Toggle_StandardContextMenu.Content\" xml:space=\"preserve\">\n    <value>右键菜单和扩展右键菜单</value>\n  </data>\n  <data name=\"PowerRename_Toggle_ExtendedContextMenu.Content\" xml:space=\"preserve\">\n    <value>仅扩展右键菜单</value>\n  </data>\n  <data name=\"ExtendedContextMenuInfo.Title\" xml:space=\"preserve\">\n    <value>Shift + 右键即可打开扩展右键菜单</value>\n  </data>\n  <data name=\"PowerRename_Toggle_MaxDispListNum.Header\" xml:space=\"preserve\">\n    <value>最大保留个数</value>\n  </data>\n  <data name=\"PowerRename_Toggle_RestoreFlagsOnLaunch.Header\" xml:space=\"preserve\">\n    <value>保留上次搜索内容</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_MD.Header\" xml:space=\"preserve\">\n    <value>Markdown 文档</value>\n    <comment>File type, do not translate</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_MD.Description\" xml:space=\"preserve\">\n    <value>.md, .markdown, .mdown, .mkdn, .mkd, .mdwn, .mdtxt, .mdtext</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_Monaco.Header\" xml:space=\"preserve\">\n    <value>程序代码</value>\n    <comment>File type, do not translate</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_Monaco.Description\" xml:space=\"preserve\">\n    <value>.txt, .cpp, .py, .json, .xml, .csproj 等，由 Monaco 编辑器提供支持</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_SVG.Header\" xml:space=\"preserve\">\n    <value>矢量图</value>\n    <comment>File type, do not translate</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_SVG.Description\" xml:space=\"preserve\">\n    <value>.svg</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Color_Mode.Header\" xml:space=\"preserve\">\n    <value>背景</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Color_Mode_Default.Content\" xml:space=\"preserve\">\n    <value>系统默认黑白</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Color_Solid_Color.Content\" xml:space=\"preserve\">\n    <value>固定颜色</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Checkered_Shade.Content\" xml:space=\"preserve\">\n    <value>格子</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Background_Color.Header\" xml:space=\"preserve\">\n    <value>颜色</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_Mode.Header\" xml:space=\"preserve\">\n    <value>格子颜色</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_1.Content\" xml:space=\"preserve\">\n    <value>浅色</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_2.Content\" xml:space=\"preserve\">\n    <value>中等色</value>\n  </data>\n  <data name=\"FileExplorerPreview_Preview_SVG_Checkered_Shade_3.Content\" xml:space=\"preserve\">\n    <value>深色</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_PDF.Header\" xml:space=\"preserve\">\n    <value>PDF 文档</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_PDF.Description\" xml:space=\"preserve\">\n    <value>.pdf</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_SVG.Header\" xml:space=\"preserve\">\n    <value>矢量图</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_SVG.Description\" xml:space=\"preserve\">\n    <value>.svg</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_STL.Header\" xml:space=\"preserve\">\n    <value>3D 模型</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_STL.Description\" xml:space=\"preserve\">\n    <value>.stl</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_Color_Thumbnail_STL.Header\" xml:space=\"preserve\">\n    <value>模型颜色</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_QOI.Header\" xml:space=\"preserve\">\n    <value>QOI 图像</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_QOI.Description\" xml:space=\"preserve\">\n    <value>.qoi</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_QOI.Header\" xml:space=\"preserve\">\n    <value>QOI 图像</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_QOI.Description\" xml:space=\"preserve\">\n    <value>.qoi</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_PDF.Header\" xml:space=\"preserve\">\n    <value>PDF 文档</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_PDF.Description\" xml:space=\"preserve\">\n    <value>.pdf</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview.ModuleDescription\" xml:space=\"preserve\">\n    <value>让文件管理器支持更多预览格式。</value>\n  </data>\n  <data name=\"PowerRename_AutoCompleteHeader.Header\" xml:space=\"preserve\">\n    <value>自动完成</value>\n  </data>\n  <data name=\"OpenSource_Notice.Text\" xml:space=\"preserve\">\n    <value>开源许可</value>\n  </data>\n  <data name=\"PowerRename_Toggle_AutoComplete.Header\" xml:space=\"preserve\">\n    <value>保留历史记录，启用自动补全</value>\n  </data>\n  <data name=\"FancyZones_BorderColor.Header\" xml:space=\"preserve\">\n    <value>边框颜色</value>\n  </data>\n  <data name=\"FancyZones_InActiveColor.Header\" xml:space=\"preserve\">\n    <value>闲置颜色</value>\n  </data>\n  <data name=\"ShortcutGuide.ModuleDescription\" xml:space=\"preserve\">\n    <value>显示一份系统快捷键表格。</value>\n  </data>\n  <data name=\"ShortcutGuide_PressTimeForGlobalWindowsShortcuts.Header\" xml:space=\"preserve\">\n    <value>显示表格的长按时间（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"ShortcutGuide_ActivationMethod.Header\" xml:space=\"preserve\">\n    <value>启动方式</value>\n  </data>\n  <data name=\"ShortcutGuide_ActivationMethod.Description\" xml:space=\"preserve\">\n    <value>打开快捷键表格的方式</value>\n  </data>\n  <data name=\"Radio_ShortcutGuide_ActivationMethod_CustomizedShortcut.Content\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"Radio_ShortcutGuide_ActivationMethod_LongPressWindowsKey.Content\" xml:space=\"preserve\">\n    <value>长按 Win 键</value>\n  </data>\n  <data name=\"ShortcutGuide_PressWinKeyWarning.Title\" xml:space=\"preserve\">\n    <value>在一些特殊情况下，长按打开可能无效</value>\n  </data>\n  <data name=\"Appearance_Behavior.Header\" xml:space=\"preserve\">\n    <value>外观</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestoreTitle.Header\" xml:space=\"preserve\">\n    <value>备份</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore.Header\" xml:space=\"preserve\">\n    <value>备份设置</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore.Description\" xml:space=\"preserve\">\n    <value>还原设置需要自动重启软件</value>\n  </data>\n  <data name=\"ShortcutGuide_Enable.Header\" xml:space=\"preserve\">\n    <value>启用快捷键指南</value>\n    <comment>do not loc the Product name. Do you want this feature on / off</comment>\n  </data>\n  <data name=\"ShortcutGuide_OverlayOpacity.Header\" xml:space=\"preserve\">\n    <value>背景不透明度（%）</value>\n  </data>\n  <data name=\"ShortcutGuide_DisabledApps.Header\" xml:space=\"preserve\">\n    <value>忽略应用列表</value>\n  </data>\n  <data name=\"ShortcutGuide_DisabledApps.Description\" xml:space=\"preserve\">\n    <value>填写忽略应用的名称，每行一个，防止在应用中误触而弹出指示图</value>\n  </data>\n  <data name=\"ShortcutGuide_DisabledApps_TextBoxControl.PlaceholderText\" xml:space=\"preserve\">\n    <value>例如: outlook.exe</value>\n    <comment>Don't translate outlook.exe</comment>\n  </data>\n  <data name=\"ImageResizer_CustomSizes.Header\" xml:space=\"preserve\">\n    <value>尺寸</value>\n  </data>\n  <data name=\"ImageResizer_Presets.Header\" xml:space=\"preserve\">\n    <value>预设</value>\n  </data>\n  <data name=\"ImageResizer_Presets.Description\" xml:space=\"preserve\">\n    <value>图像裁剪的尺寸预设</value>\n  </data>\n  <data name=\"ImageResizer_FilenameFormatHeader.Description\" xml:space=\"preserve\">\n    <value>图片裁剪完成后，保存的文件名格式</value>\n  </data>\n  <data name=\"ImageResizer.ModuleDescription\" xml:space=\"preserve\">\n    <value>右键即可调整图像大小。</value>\n  </data>\n  <data name=\"ImageResizer_EnableToggle.Header\" xml:space=\"preserve\">\n    <value>启用图像裁剪器</value>\n    <comment>do not loc the Product name.  Do you want this feature on / off</comment>\n  </data>\n  <data name=\"ImagesSizesListView.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>尺寸预设</value>\n  </data>\n  <data name=\"ImageResizer_Configurations.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>尺寸预设配置</value>\n  </data>\n  <data name=\"ImageResizer_Name.Header\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"ImageResizer_Fit.Header\" xml:space=\"preserve\">\n    <value>操作</value>\n  </data>\n  <data name=\"ImageResizer_Width.Header\" xml:space=\"preserve\">\n    <value>宽度</value>\n  </data>\n  <data name=\"ImageResizer_Height.Header\" xml:space=\"preserve\">\n    <value>高度</value>\n  </data>\n  <data name=\"ImageResizer_Size.Header\" xml:space=\"preserve\">\n    <value>单位</value>\n  </data>\n  <data name=\"RemoveItem.Text\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"ImageResizer_Image.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n  </data>\n  <data name=\"ImageResizer_AddSizeButton.Content\" xml:space=\"preserve\">\n    <value>添加</value>\n  </data>\n  <data name=\"ImageResizer_SaveSizeButton.Label\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"ImageResizer_Encoding.Header\" xml:space=\"preserve\">\n    <value>JPEG 压缩质量（%）</value>\n    <comment>{Locked=\"JPEG\"}</comment>\n  </data>\n  <data name=\"ImageResizer_PNGInterlacing.Header\" xml:space=\"preserve\">\n    <value>PNG 隔行扫描</value>\n    <comment>{Locked=\"PNG\"}</comment>\n  </data>\n  <data name=\"ImageResizer_TIFFCompression.Header\" xml:space=\"preserve\">\n    <value>TIFF 压缩格式</value>\n    <comment>{Locked=\"TIFF\"}</comment>\n  </data>\n  <data name=\"File.Header\" xml:space=\"preserve\">\n    <value>文件</value>\n    <comment>as in a computer file</comment>\n  </data>\n  <data name=\"Default.Content\" xml:space=\"preserve\">\n    <value>默认</value>\n  </data>\n  <data name=\"ImageResizer_ENCODER_TIFF_CCITT3.Content\" xml:space=\"preserve\">\n    <value>CCITT3</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"ImageResizer_ENCODER_TIFF_CCITT4.Content\" xml:space=\"preserve\">\n    <value>CCITT4</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"ImageResizer_ENCODER_TIFF_Default.Content\" xml:space=\"preserve\">\n    <value>默认</value>\n  </data>\n  <data name=\"ImageResizer_ENCODER_TIFF_LZW.Content\" xml:space=\"preserve\">\n    <value>LZW</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"ImageResizer_ENCODER_TIFF_None.Content\" xml:space=\"preserve\">\n    <value>无</value>\n  </data>\n  <data name=\"ImageResizer_ENCODER_TIFF_RLE.Content\" xml:space=\"preserve\">\n    <value>RLE</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"ImageResizer_ENCODER_TIFF_Zip.Content\" xml:space=\"preserve\">\n    <value>Zip</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"ImageResizer_FallbackEncoder_BMP.Content\" xml:space=\"preserve\">\n    <value>BMP 编码器</value>\n    <comment>{Locked=\"BMP\"}</comment>\n  </data>\n  <data name=\"ImageResizer_FallbackEncoder_GIF.Content\" xml:space=\"preserve\">\n    <value>GIF 编码器</value>\n    <comment>{Locked=\"GIF\"}</comment>\n  </data>\n  <data name=\"ImageResizer_FallbackEncoder_JPEG.Content\" xml:space=\"preserve\">\n    <value>JPEG 编码器</value>\n    <comment>{Locked=\"JPEG\"}</comment>\n  </data>\n  <data name=\"ImageResizer_FallbackEncoder_PNG.Content\" xml:space=\"preserve\">\n    <value>PNG 编码器</value>\n    <comment>{Locked=\"PNG\"}</comment>\n  </data>\n  <data name=\"ImageResizer_FallbackEncoder_TIFF.Content\" xml:space=\"preserve\">\n    <value>TIFF 编码器</value>\n    <comment>{Locked=\"TIFF\"}</comment>\n  </data>\n  <data name=\"ImageResizer_FallbackEncoder_WMPhoto.Content\" xml:space=\"preserve\">\n    <value>WMPhoto 编码器</value>\n    <comment>{Locked=\"WMPhoto\"}</comment>\n  </data>\n  <data name=\"ImageResizer_Sizes_Fit_Fill.Content\" xml:space=\"preserve\">\n    <value>填充</value>\n    <comment>Refers to filling an image into a certain size. It could overflow</comment>\n  </data>\n  <data name=\"ImageResizer_Sizes_Fit_Fill_ThirdPersonSingular.Text\" xml:space=\"preserve\">\n    <value>模式</value>\n    <comment>Refers to filling an image into a certain size. It could overflow</comment>\n  </data>\n  <data name=\"ImageResizer_Sizes_Fit_Fit.Content\" xml:space=\"preserve\">\n    <value>缩放</value>\n    <comment>Refers to fitting an image into a certain size. It won't overflow</comment>\n  </data>\n  <data name=\"ImageResizer_Sizes_Fit_Stretch.Content\" xml:space=\"preserve\">\n    <value>拉伸</value>\n    <comment>Refers to stretching an image into a certain size. Won't overflow but could distort.</comment>\n  </data>\n  <data name=\"ImageResizer_Sizes_Units_CM.Content\" xml:space=\"preserve\">\n    <value>厘米</value>\n  </data>\n  <data name=\"ImageResizer_Sizes_Units_Inches.Content\" xml:space=\"preserve\">\n    <value>英寸</value>\n  </data>\n  <data name=\"ImageResizer_Sizes_Units_Percent.Content\" xml:space=\"preserve\">\n    <value>百分比</value>\n  </data>\n  <data name=\"ImageResizer_Sizes_Units_Pixels.Content\" xml:space=\"preserve\">\n    <value>像素</value>\n  </data>\n  <data name=\"Off.Content\" xml:space=\"preserve\">\n    <value>关</value>\n  </data>\n  <data name=\"On.Content\" xml:space=\"preserve\">\n    <value>开</value>\n  </data>\n  <data name=\"GeneralPage_ToggleSwitch_AlwaysRunElevated_Link.Content\" xml:space=\"preserve\">\n    <value>详细了解管理员模式</value>\n  </data>\n  <data name=\"GeneralPage_AutoDownloadAndInstallUpdates.Header\" xml:space=\"preserve\">\n    <value>自动下载并安装更新</value>\n  </data>\n  <data name=\"GeneralPage_AutoDownloadAndInstallUpdates.Description\" xml:space=\"preserve\">\n    <value>除非处于按流量计费的网络</value>\n  </data>\n  <data name=\"GeneralPage_ToggleSwitch_RunningAsAdminNote.Text\" xml:space=\"preserve\">\n    <value>当前正以管理员身份运行</value>\n  </data>\n  <data name=\"GeneralSettings_AlwaysRunAsAdminText.Header\" xml:space=\"preserve\">\n    <value>始终以管理员身份运行</value>\n  </data>\n  <data name=\"GeneralSettings_AlwaysRunAsAdminText.Description\" xml:space=\"preserve\">\n    <value>要更改此设置，请以管理员身份重新启动软件</value>\n  </data>\n  <data name=\"GeneralSettings_RunningAsUserText\" xml:space=\"preserve\">\n    <value>当前正以用户身份运行</value>\n  </data>\n  <data name=\"GeneralSettings_RunningAsAdminText\" xml:space=\"preserve\">\n    <value>当前正以管理员身份运行</value>\n  </data>\n  <data name=\"FancyZones.ModuleTitle\" xml:space=\"preserve\">\n    <value>窗口布局</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"FileExplorerPreview.ModuleTitle\" xml:space=\"preserve\">\n    <value>预览增强</value>\n  </data>\n  <data name=\"FileExplorerPreview_Image.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>预览增强</value>\n    <comment>Use same translation as Windows does for File Explorer</comment>\n  </data>\n  <data name=\"ImageResizer.ModuleTitle\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n  </data>\n  <data name=\"KeyboardManager.ModuleTitle\" xml:space=\"preserve\">\n    <value>键盘修改器</value>\n  </data>\n  <data name=\"ColorPicker.ModuleTitle\" xml:space=\"preserve\">\n    <value>取色器</value>\n  </data>\n  <data name=\"PowerLauncher.ModuleTitle\" xml:space=\"preserve\">\n    <value>快捷启动器</value>\n  </data>\n  <data name=\"PowerToys_Run_Image.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>快捷启动器</value>\n  </data>\n  <data name=\"PowerRename.ModuleTitle\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>do not loc the product name</comment>\n  </data>\n  <data name=\"PowerRename_Image.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>do not loc</comment>\n  </data>\n  <data name=\"ShortcutGuide.ModuleTitle\" xml:space=\"preserve\">\n    <value>快捷键指南</value>\n  </data>\n  <data name=\"Shortcut_Guide_Image.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>快捷键指南</value>\n  </data>\n  <data name=\"General_Repository.Text\" xml:space=\"preserve\">\n    <value>开源仓库</value>\n  </data>\n  <data name=\"General_VersionAndUpdate.Header\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"General_VersionLastChecked.Text\" xml:space=\"preserve\">\n    <value>检查时间: </value>\n  </data>\n  <data name=\"General_SettingsBackupInfo_DateHeader.Text\" xml:space=\"preserve\">\n    <value>时间:</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestoreStatusInfo.Header\" xml:space=\"preserve\">\n    <value>详细信息</value>\n  </data>\n  <data name=\"General_SettingsBackupInfo_SourceHeader.Text\" xml:space=\"preserve\">\n    <value>来源:</value>\n  </data>\n  <data name=\"General_SettingsBackupInfo_StatusHeader.Text\" xml:space=\"preserve\">\n    <value>状态:</value>\n  </data>\n  <data name=\"General_VersionAndUpdate.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"Admin_mode.Header\" xml:space=\"preserve\">\n    <value>管理员模式</value>\n  </data>\n  <data name=\"FancyZones_RestoreSize.Content\" xml:space=\"preserve\">\n    <value>解除布局时，还原窗口的原始大小</value>\n  </data>\n  <data name=\"ImageResizer_FallBackEncoderText.Header\" xml:space=\"preserve\">\n    <value>备用编码器</value>\n  </data>\n  <data name=\"ImageResizer_FallBackEncoderText.Description\" xml:space=\"preserve\">\n    <value>不支持原文件的编码格式时备用的编码格式</value>\n  </data>\n  <data name=\"ImageResizer_FileFormatDescription.Text\" xml:space=\"preserve\">\n    <value>可以使用以下参数：</value>\n  </data>\n  <data name=\"ImageResizer_FilenameFormatHeader.Header\" xml:space=\"preserve\">\n    <value>文件名格式</value>\n  </data>\n  <data name=\"ImageResizer_FileModifiedDate.Header\" xml:space=\"preserve\">\n    <value>文件时间戳</value>\n  </data>\n  <data name=\"ImageResizer_FileModifiedDate.Description\" xml:space=\"preserve\">\n    <value>裁剪后文件的“修改时间”属性</value>\n  </data>\n  <data name=\"ImageResizer_UseOriginalDate.Content\" xml:space=\"preserve\">\n    <value>原文件时间</value>\n  </data>\n  <data name=\"ImageResizer_UseResizeDate.Content\" xml:space=\"preserve\">\n    <value>裁剪时间</value>\n  </data>\n  <data name=\"Encoding.Header\" xml:space=\"preserve\">\n    <value>编码</value>\n  </data>\n  <data name=\"KeyboardManager_RemapKeyboardButton.Description\" xml:space=\"preserve\">\n    <value>修改单个按键对应的功能</value>\n  </data>\n  <data name=\"KeyboardManager_RemapShortcutsButton.Description\" xml:space=\"preserve\">\n    <value>修改组合键对应的功能，可以限定程序</value>\n  </data>\n  <data name=\"General.ModuleDescription\" xml:space=\"preserve\">\n    <value>Microsoft PowerToys 是一个工具箱，可以优化 Windows 操作，提高工作效率。\n本项目由微软与 PowerToys 社区共同成就，用💗呈现。</value>\n    <comment>Windows refers to the OS</comment>\n  </data>\n  <data name=\"FancyZones_SpanZonesAcrossMonitors.Header\" xml:space=\"preserve\">\n    <value>允许布局跨显示器</value>\n  </data>\n  <data name=\"ImageResizer_Formatting_ActualHeight.Text\" xml:space=\"preserve\">\n    <value>实际高度</value>\n  </data>\n  <data name=\"ImageResizer_Formatting_ActualWidth.Text\" xml:space=\"preserve\">\n    <value>实际宽度</value>\n  </data>\n  <data name=\"ImageResizer_Formatting_Filename.Text\" xml:space=\"preserve\">\n    <value>原文件名</value>\n  </data>\n  <data name=\"ImageResizer_Formatting_SelectedHeight.Text\" xml:space=\"preserve\">\n    <value>设定高度</value>\n  </data>\n  <data name=\"ImageResizer_Formatting_SelectedWidth.Text\" xml:space=\"preserve\">\n    <value>设定宽度</value>\n  </data>\n  <data name=\"ImageResizer_Formatting_Sizename.Text\" xml:space=\"preserve\">\n    <value>尺寸名称</value>\n  </data>\n  <data name=\"FancyZones_MoveWindowsBasedOnPositionCheckBoxControl.Content\" xml:space=\"preserve\">\n    <value>根据窗口位置移动</value>\n    <comment>Windows refers to application windows</comment>\n  </data>\n  <data name=\"GeneralSettings_NewVersionIsAvailable\" xml:space=\"preserve\">\n    <value>有版本更新</value>\n  </data>\n  <data name=\"GeneralSettings_VersionIsLatest\" xml:space=\"preserve\">\n    <value>已是最新版本</value>\n  </data>\n  <data name=\"FileExplorerPreview_IconThumbnail_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>文件缩略图</value>\n  </data>\n  <data name=\"FileExplorerPreview_IconThumbnail_GroupSettings.Description\" xml:space=\"preserve\">\n    <value>选择要显示缩略图的文件格式</value>\n  </data>\n  <data name=\"FileExplorerPreview_PreviewPane.Header\" xml:space=\"preserve\">\n    <value>预览窗格</value>\n  </data>\n  <data name=\"FileExplorerPreview_PreviewPane.Description\" xml:space=\"preserve\">\n    <value>选择要预览的文件格式，在文件夹中按 Alt + P 即可打开预览窗格</value>\n    <comment>Preview Pane and File Explorer are app/feature names in Windows. 'Alt + P' is a shortcut</comment>\n  </data>\n  <data name=\"FileExplorerPreview_RunAsAdminRequired.Title\" xml:space=\"preserve\">\n    <value>要更改此设置，请以管理员身份重新启动软件</value>\n  </data>\n  <data name=\"FileExplorerPreview_RebootRequired.Title\" xml:space=\"preserve\">\n    <value>为了使更改生效，可能需要重启电脑</value>\n  </data>\n  <data name=\"FileExplorerPreview_PreviewHandlerOutlookIncompatibility.Title\" xml:space=\"preserve\">\n    <value>开启文件预览将会代替其他软件的预览功能 - 比如 PDF 预览功能可能不兼容 Outlook 的预览</value>\n    <comment>Outlook is the name of a Microsoft product</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ThumbnailsMightNotAppearOnRemoteFolders.Title\" xml:space=\"preserve\">\n    <value>缩略图可能不支持 OneDrive 等网盘的同步目录，因为网盘文件的缩略图会从网盘获取，而不是在本地生成</value>\n    <comment>OneDrive is the name of a Microsoft product</comment>\n  </data>\n  <data name=\"FancyZones_ExcludeApps_TextBoxControl.PlaceholderText\" xml:space=\"preserve\">\n    <value>例如: outlook.exe</value>\n    <comment>{Locked=\"outlook.exe\"}</comment>\n  </data>\n  <data name=\"ImageResizer_FilenameFormatPlaceholder.PlaceholderText\" xml:space=\"preserve\">\n    <value>例如: %1 (%2)</value>\n  </data>\n  <data name=\"ImageResizer_FilenameParameters.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>文件名参数</value>\n  </data>\n  <data name=\"Radio_Theme_Dark.Content\" xml:space=\"preserve\">\n    <value>暗</value>\n    <comment>Dark refers to color, not weight</comment>\n  </data>\n  <data name=\"Radio_Theme_Light.Content\" xml:space=\"preserve\">\n    <value>亮</value>\n    <comment>Light refers to color, not weight</comment>\n  </data>\n  <data name=\"Radio_Theme_Default.Content\" xml:space=\"preserve\">\n    <value>系统默认</value>\n    <comment>Windows refers to the Operating system</comment>\n  </data>\n  <data name=\"Windows_Color_Settings.Content\" xml:space=\"preserve\">\n    <value>Windows 颜色设置</value>\n    <comment>Windows refers to the Operating system</comment>\n  </data>\n  <data name=\"ColorPicker_CopiedColorRepresentation.Header\" xml:space=\"preserve\">\n    <value>颜色格式</value>\n  </data>\n  <data name=\"ColorPickerFirst.Content\" xml:space=\"preserve\">\n    <value>取色到调色板</value>\n  </data>\n  <data name=\"EditorFirst.Content\" xml:space=\"preserve\">\n    <value>打开调色板</value>\n  </data>\n  <data name=\"ColorPickerOnly.Content\" xml:space=\"preserve\">\n    <value>仅复制颜色</value>\n  </data>\n  <data name=\"ColorPicker_ActivationAction.Header\" xml:space=\"preserve\">\n    <value>启动模式</value>\n  </data>\n  <data name=\"ColorFormats.Header\" xml:space=\"preserve\">\n    <value>取色器</value>\n  </data>\n  <data name=\"ColorPicker_CopiedColorRepresentation.Description\" xml:space=\"preserve\">\n    <value>复制到剪贴板的颜色格式</value>\n  </data>\n  <data name=\"KBM_KeysCannotBeRemapped.Text\" xml:space=\"preserve\">\n    <value>详细了解修改键盘的限制</value>\n    <comment>This is a link that will discuss what is and is not possible for Keyboard manager to remap</comment>\n  </data>\n  <data name=\"FancyZones_Editor_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>编辑器</value>\n    <comment>refers to the FancyZones editor</comment>\n  </data>\n  <data name=\"FancyZones_WindowBehavior_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>窗口功能</value>\n  </data>\n  <data name=\"FancyZones_WindowBehavior_GroupSettings.Description\" xml:space=\"preserve\">\n    <value>管理窗口的功能</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"FancyZones_Windows.Header\" xml:space=\"preserve\">\n    <value>窗口</value>\n    <comment>Refers to a set of application windows, not the product name</comment>\n  </data>\n  <data name=\"PowerRename_BehaviorHeader.Header\" xml:space=\"preserve\">\n    <value>附加功能</value>\n  </data>\n  <data name=\"PowerRename_Toggle_UseBoostLib.Header\" xml:space=\"preserve\">\n    <value>使用增强版引擎</value>\n    <comment>Boost is a product name, should not be translated</comment>\n  </data>\n  <data name=\"PowerRename_Toggle_UseBoostLib.Description\" xml:space=\"preserve\">\n    <value>Boost 正则库，提供更多功能，但语法有所不同</value>\n    <comment>Boost is a product name, should not be translated</comment>\n  </data>\n  <data name=\"MadeWithOssLove.Text\" xml:space=\"preserve\">\n    <value>由微软和 PowerToys 社区用 💗 制作。</value>\n  </data>\n  <data name=\"ColorPicker_ColorFormats.Header\" xml:space=\"preserve\">\n    <value>颜色格式</value>\n  </data>\n  <data name=\"ColorPicker_ColorFormats.Description\" xml:space=\"preserve\">\n    <value>配置调色板中显示的颜色格式</value>\n  </data>\n  <data name=\"MoveUp.Text\" xml:space=\"preserve\">\n    <value>上移</value>\n  </data>\n  <data name=\"MoveDown.Text\" xml:space=\"preserve\">\n    <value>下移</value>\n  </data>\n  <data name=\"ColorPickerAddNewFormat.Content\" xml:space=\"preserve\">\n    <value>添加</value>\n  </data>\n  <data name=\"NewColorFormat.Header\" xml:space=\"preserve\">\n    <value>格式</value>\n  </data>\n  <data name=\"NewColorName.Header\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"AddCustomColorFormat\" xml:space=\"preserve\">\n    <value>添加颜色格式</value>\n  </data>\n  <data name=\"ColorFormatSave\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"EditCustomColorFormat\" xml:space=\"preserve\">\n    <value>编辑颜色格式</value>\n  </data>\n  <data name=\"ColorFormatUpdate\" xml:space=\"preserve\">\n    <value>更新</value>\n  </data>\n  <data name=\"CustomColorFormatDefaultName\" xml:space=\"preserve\">\n    <value>自定义格式</value>\n  </data>\n  <data name=\"ColorFormatDialog.SecondaryButtonText\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"ColorFormatEditorHelpline1.Text\" xml:space=\"preserve\">\n    <value>可以使用以下参数：</value>\n  </data>\n  <data name=\"Help_red\" xml:space=\"preserve\">\n    <value>RGB 红色</value>\n  </data>\n  <data name=\"Help_green\" xml:space=\"preserve\">\n    <value>RGB 绿色</value>\n  </data>\n  <data name=\"Help_blue\" xml:space=\"preserve\">\n    <value>RGB 蓝色</value>\n  </data>\n  <data name=\"Help_alpha\" xml:space=\"preserve\">\n    <value>透明度</value>\n  </data>\n  <data name=\"Help_cyan\" xml:space=\"preserve\">\n    <value>CMYK 青色</value>\n  </data>\n  <data name=\"Help_magenta\" xml:space=\"preserve\">\n    <value>CMYK 洋红</value>\n  </data>\n  <data name=\"Help_yellow\" xml:space=\"preserve\">\n    <value>CMYK 黄色</value>\n  </data>\n  <data name=\"Help_black_key\" xml:space=\"preserve\">\n    <value>CMYK 黑色</value>\n  </data>\n  <data name=\"Help_hue\" xml:space=\"preserve\">\n    <value>色调</value>\n  </data>\n  <data name=\"Help_hueNat\" xml:space=\"preserve\">\n    <value>视觉色调</value>\n  </data>\n  <data name=\"Help_saturationI\" xml:space=\"preserve\">\n    <value>HSI 饱和度</value>\n  </data>\n  <data name=\"Help_saturationL\" xml:space=\"preserve\">\n    <value>HSL 饱和度</value>\n  </data>\n  <data name=\"Help_saturationB\" xml:space=\"preserve\">\n    <value>HSB 饱和度</value>\n  </data>\n  <data name=\"Help_brightness\" xml:space=\"preserve\">\n    <value>HSB 亮度</value>\n  </data>\n  <data name=\"Help_intensity\" xml:space=\"preserve\">\n    <value>HSI 纯度</value>\n  </data>\n  <data name=\"Help_lightnessNat\" xml:space=\"preserve\">\n    <value>视觉亮度</value>\n  </data>\n  <data name=\"Help_lightnessCIE\" xml:space=\"preserve\">\n    <value>CIE 亮度</value>\n  </data>\n  <data name=\"Help_value\" xml:space=\"preserve\">\n    <value>HSV 明度</value>\n  </data>\n  <data name=\"Help_whiteness\" xml:space=\"preserve\">\n    <value>HWB 白度</value>\n  </data>\n  <data name=\"Help_blackness\" xml:space=\"preserve\">\n    <value>HWB 黑度</value>\n  </data>\n  <data name=\"Help_chromaticityA\" xml:space=\"preserve\">\n    <value>CIELAB 色度 A</value>\n  </data>\n  <data name=\"Help_chromaticityB\" xml:space=\"preserve\">\n    <value>CIELAB 色度 B</value>\n  </data>\n  <data name=\"Help_X_value\" xml:space=\"preserve\">\n    <value>CIEXYZ X 值</value>\n  </data>\n  <data name=\"Help_Y_value\" xml:space=\"preserve\">\n    <value>CIEXYZ Y 值</value>\n  </data>\n  <data name=\"Help_Z_value\" xml:space=\"preserve\">\n    <value>CIEXYZ Z 值</value>\n  </data>\n  <data name=\"Help_decimal_value_RGB\" xml:space=\"preserve\">\n    <value>RGB 十进制数字</value>\n  </data>\n  <data name=\"Help_decimal_value_BGR\" xml:space=\"preserve\">\n    <value>BGR 十进制数字</value>\n  </data>\n  <data name=\"Help_color_name\" xml:space=\"preserve\">\n    <value>颜色名称</value>\n  </data>\n  <data name=\"ColorFormatEditorHelpline2.Text\" xml:space=\"preserve\">\n    <value>红色、绿色、蓝色、透明度可以使用以下后缀改变格式：</value>\n  </data>\n  <data name=\"Help_byte\" xml:space=\"preserve\">\n    <value>整数 0~255（默认）</value>\n  </data>\n  <data name=\"Help_hexL1\" xml:space=\"preserve\">\n    <value>十六进制一位小写</value>\n  </data>\n  <data name=\"Help_hexU1\" xml:space=\"preserve\">\n    <value>十六进制一位大写</value>\n  </data>\n  <data name=\"Help_hexL2\" xml:space=\"preserve\">\n    <value>十六进制两位小写</value>\n  </data>\n  <data name=\"Help_hexU2\" xml:space=\"preserve\">\n    <value>十六进制两位大写</value>\n  </data>\n  <data name=\"Help_floatWith\" xml:space=\"preserve\">\n    <value>小数</value>\n  </data>\n  <data name=\"Help_floatWithout\" xml:space=\"preserve\">\n    <value>小数前面去掉零</value>\n  </data>\n  <data name=\"ColorFormatEditorHelpline3.Text\" xml:space=\"preserve\">\n    <value>例如：%ReX 表示一个十六进制两位大写的 RGB 红色值</value>\n  </data>\n  <data name=\"ColorPicker_ShowColorName.Header\" xml:space=\"preserve\">\n    <value>显示颜色名称</value>\n  </data>\n  <data name=\"ColorPicker_ShowColorName.Description\" xml:space=\"preserve\">\n    <value>取色时显示颜色的名称，比如红色</value>\n  </data>\n  <data name=\"ImageResizer_DefaultSize_Large\" xml:space=\"preserve\">\n    <value>大号</value>\n    <comment>The size of the image</comment>\n  </data>\n  <data name=\"ImageResizer_DefaultSize_Medium\" xml:space=\"preserve\">\n    <value>中号</value>\n    <comment>The size of the image</comment>\n  </data>\n  <data name=\"ImageResizer_DefaultSize_Phone\" xml:space=\"preserve\">\n    <value>流畅</value>\n    <comment>The size of the image referring to a Mobile Phone typical image size</comment>\n  </data>\n  <data name=\"ImageResizer_DefaultSize_Small\" xml:space=\"preserve\">\n    <value>小号</value>\n    <comment>The size of the image</comment>\n  </data>\n  <data name=\"FancyZones_MoveWindowBasedOnRelativePosition_Accessible.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>Win + ↑ ↓ ← → 按相对位置在布局内移动</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"FancyZones_MoveWindowLeftRightBasedOnZoneIndex_Accessible.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>Win + ← → 在布局内移动，↑ ↓ 全屏和最小化</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"FancyZones_MoveWindowBasedOnRelativePosition_Description.Text\" xml:space=\"preserve\">\n    <value>Win +    </value>\n    <comment>{Locked=\"Windows key +   \",\"\"}</comment>\n  </data>\n  <data name=\"FancyZones_MoveWindowLeftRightBasedOnZoneIndex_Description.Text\" xml:space=\"preserve\">\n    <value>Win +  </value>\n    <comment>{Locked=\"Windows key + \",\"\"}</comment>\n  </data>\n  <data name=\"FancyZones_MoveWindowBasedOnRelativePosition.Text\" xml:space=\"preserve\">\n    <value>相对位置</value>\n  </data>\n  <data name=\"FancyZones_MoveWindow.Header\" xml:space=\"preserve\">\n    <value>控制模式</value>\n  </data>\n  <data name=\"FancyZones_MoveWindowLeftRightBasedOnZoneIndex.Text\" xml:space=\"preserve\">\n    <value>排列顺序</value>\n  </data>\n  <data name=\"ColorPicker_Editor.Header\" xml:space=\"preserve\">\n    <value>调色板</value>\n  </data>\n  <data name=\"FancyZones_OverlappingZonesClosestCenter.Content\" xml:space=\"preserve\">\n    <value>激活区块中心离鼠标最近的布局区</value>\n  </data>\n  <data name=\"FancyZones_OverlappingZonesLargest.Content\" xml:space=\"preserve\">\n    <value>激活最大的布局区</value>\n  </data>\n  <data name=\"FancyZones_OverlappingZonesPositional.Content\" xml:space=\"preserve\">\n    <value>划分重叠的部分</value>\n  </data>\n  <data name=\"FancyZones_OverlappingZonesSmallest.Content\" xml:space=\"preserve\">\n    <value>激活最小的布局区</value>\n  </data>\n  <data name=\"FancyZones_OverlappingZones.Header\" xml:space=\"preserve\">\n    <value>布局区重叠处理</value>\n  </data>\n  <data name=\"PowerLauncher_Plugins.Header\" xml:space=\"preserve\">\n    <value>插件</value>\n  </data>\n  <data name=\"PowerLauncher_ActionKeyword.Header\" xml:space=\"preserve\">\n    <value>唤醒词</value>\n  </data>\n  <data name=\"PowerLauncher_AuthoredBy.Text\" xml:space=\"preserve\">\n    <value>作者</value>\n    <comment>example: Authored by Microsoft</comment>\n  </data>\n  <data name=\"PowerLauncher_IncludeInGlobalResultTitle.Text\" xml:space=\"preserve\">\n    <value>默认唤醒</value>\n  </data>\n  <data name=\"PowerLauncher_IncludeInGlobalResultDescription.Text\" xml:space=\"preserve\">\n    <value>没有任何唤醒词时也显示</value>\n  </data>\n  <data name=\"PowerLauncher_EnablePluginToggle.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>启用插件</value>\n  </data>\n  <data name=\"PowerLauncher_EnablePluginToggle.OnContent\" xml:space=\"preserve\">\n    <value>开</value>\n  </data>\n  <data name=\"PowerLauncher_EnablePluginToggle.OffContent\" xml:space=\"preserve\">\n    <value>关</value>\n  </data>\n  <data name=\"Run_AdditionalOptions.Text\" xml:space=\"preserve\">\n    <value>附加选项</value>\n  </data>\n  <data name=\"Run_NotAccessibleWarning.Title\" xml:space=\"preserve\">\n    <value>请定义唤醒词，或开启默认唤醒，从而启动插件功能</value>\n  </data>\n  <data name=\"Run_AllPluginsDisabled.Title\" xml:space=\"preserve\">\n    <value>启动器无法启动任何功能，因为所有插件都被关闭了</value>\n  </data>\n  <data name=\"Run_AllPluginsDisabled.Message\" xml:space=\"preserve\">\n    <value>试试开启一个插件</value>\n  </data>\n  <data name=\"Run_PluginUse.Header\" xml:space=\"preserve\">\n    <value>插件列表</value>\n  </data>\n  <data name=\"Run_PluginUseDescription.Text\" xml:space=\"preserve\">\n    <value>在搜索结果中开启各种插件，更改触发方式，调整附加选项</value>\n  </data>\n  <data name=\"Run_PositionAppearance_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>外观</value>\n  </data>\n  <data name=\"Run_PositionHeader.Header\" xml:space=\"preserve\">\n    <value>显示位置</value>\n    <comment>as in Show PowerToys Run on primary monitor</comment>\n  </data>\n  <data name=\"Run_PositionHeader.Description\" xml:space=\"preserve\">\n    <value>若使用多显示器，可在需要的显示器上启动</value>\n    <comment>as in Show PowerToys Run on primary monitor</comment>\n  </data>\n  <data name=\"Run_Radio_Position_Cursor.Content\" xml:space=\"preserve\">\n    <value>鼠标光标所在显示器</value>\n  </data>\n  <data name=\"Run_Radio_Position_Focus.Content\" xml:space=\"preserve\">\n    <value>窗口焦点所在显示器</value>\n  </data>\n  <data name=\"Run_Radio_Position_Primary_Monitor.Content\" xml:space=\"preserve\">\n    <value>主显示器</value>\n  </data>\n  <data name=\"Run_PluginsLoading.Text\" xml:space=\"preserve\">\n    <value>插件加载中...</value>\n  </data>\n  <data name=\"ColorPicker_ButtonDown.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>下移颜色</value>\n  </data>\n  <data name=\"ColorPicker_ButtonUp.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>上移颜色</value>\n  </data>\n  <data name=\"FancyZones_FlashZonesOnQuickSwitch.Content\" xml:space=\"preserve\">\n    <value>快速切换时显示布局</value>\n  </data>\n  <data name=\"FancyZones_Layouts.Header\" xml:space=\"preserve\">\n    <value>切换</value>\n  </data>\n  <data name=\"FancyZones_QuickLayoutSwitch.Header\" xml:space=\"preserve\">\n    <value>启用快速布局切换</value>\n  </data>\n  <data name=\"FancyZones_QuickLayoutSwitch.Description\" xml:space=\"preserve\">\n    <value>在编辑器里设置一个布局的快速切换键（0-9），按下 Ctrl + Win + Alt + 切换键，即可快速切换布局</value>\n  </data>\n  <data name=\"FancyZones_QuickLayoutSwitch_GroupSettings.Text\" xml:space=\"preserve\">\n    <value>快速布局切换</value>\n  </data>\n  <data name=\"Activation_Shortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"Activation_Shortcut.Description\" xml:space=\"preserve\">\n    <value>启动此功能的快捷键</value>\n  </data>\n  <data name=\"PasteAsPlainText_Shortcut.Header\" xml:space=\"preserve\">\n    <value>粘贴为纯文本</value>\n  </data>\n  <data name=\"AdvancedPasteUI_Actions.Header\" xml:space=\"preserve\">\n    <value>自定义操作</value>\n  </data>\n  <data name=\"AdvancedPasteUI_Actions.Description\" xml:space=\"preserve\">\n    <value>创建自定义格式粘贴操作，需要启用 AI 粘贴</value>\n  </data>\n  <data name=\"AdvancedPasteUI_AddCustomActionButton.Content\" xml:space=\"preserve\">\n    <value>添加自定义操作</value>\n  </data>\n  <data name=\"AdvancedPasteUI_Shortcut.Header\" xml:space=\"preserve\">\n    <value>打开高级粘贴面板</value>\n  </data>\n  <data name=\"AdvancedPasteUI_NewCustomActionPrefix\" xml:space=\"preserve\">\n    <value>新建自定义操作</value>\n    <comment>First part of the default name of new custom action that can be added in PT's settings ui.</comment>\n  </data>\n  <data name=\"AdvancedPasteUI_CustomAction_Name.Header\" xml:space=\"preserve\">\n    <value>名称</value>\n  </data>\n  <data name=\"AdvancedPasteUI_CustomAction_Prompt.Header\" xml:space=\"preserve\">\n    <value>提示词</value>\n  </data>\n  <data name=\"CustomActionDialog.SecondaryButtonText\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"AddCustomAction\" xml:space=\"preserve\">\n    <value>添加自定义操作</value>\n  </data>\n  <data name=\"CustomActionSave\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"EditCustomAction\" xml:space=\"preserve\">\n    <value>编辑自定义操作</value>\n  </data>\n  <data name=\"CustomActionUpdate\" xml:space=\"preserve\">\n    <value>更新</value>\n  </data>\n  <data name=\"PasteAsMarkdown_Shortcut.Header\" xml:space=\"preserve\">\n    <value>粘贴为 Markdown</value>\n  </data>\n  <data name=\"PasteAsJson_Shortcut.Header\" xml:space=\"preserve\">\n    <value>粘贴为 JSON</value>\n  </data>\n  <data name=\"PasteAsCustom_Shortcut.Header\" xml:space=\"preserve\">\n    <value>粘贴为自定义 AI 格式</value>\n  </data>\n  <data name=\"ImageToText.Header\" xml:space=\"preserve\">\n    <value>图像转文本</value>\n  </data>\n  <data name=\"PasteAsFile.Header\" xml:space=\"preserve\">\n    <value>粘贴为文件</value>\n  </data>\n  <data name=\"PasteAsTxtFile.Header\" xml:space=\"preserve\">\n    <value>粘贴为 .txt 文件</value>\n  </data>\n  <data name=\"PasteAsPngFile.Header\" xml:space=\"preserve\">\n    <value>粘贴为 .png 文件</value>\n  </data>\n  <data name=\"PasteAsHtmlFile.Header\" xml:space=\"preserve\">\n    <value>粘贴为 .html 文件</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialogOpenAIApiKey.Text\" xml:space=\"preserve\">\n    <value>OpenAI API 密钥:</value>\n  </data>\n  <data name=\"EnableAIDialog_SaveBtnText\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"EnableAIDialog_CancelBtnText\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"Oobe_GetStarted.Text\" xml:space=\"preserve\">\n    <value>让我们开始吧！</value>\n  </data>\n  <data name=\"Oobe_PowerToysDescription.Text\" xml:space=\"preserve\">\n    <value>欢迎使用 PowerToys！以下介绍将很快可以帮助您学会软件的基本使用方法。</value>\n  </data>\n  <data name=\"Oobe_GettingStarted.Text\" xml:space=\"preserve\">\n    <value>开始上手</value>\n  </data>\n  <data name=\"Oobe_Launch.Text\" xml:space=\"preserve\">\n    <value>启动</value>\n  </data>\n  <data name=\"Launch_ColorPicker.Content\" xml:space=\"preserve\">\n    <value>启动取色器</value>\n  </data>\n  <data name=\"Oobe_LearnMore.Text\" xml:space=\"preserve\">\n    <value>了解详情</value>\n  </data>\n  <data name=\"Oobe_ColorPicker.Description\" xml:space=\"preserve\">\n    <value>一个简单好用的屏幕取色器，可以从任何软件上抓取颜色，并以指定格式复制到剪贴板。</value>\n  </data>\n  <data name=\"Oobe_FancyZones.Description\" xml:space=\"preserve\">\n    <value>一个窗口管理器，可将窗口排列对齐到一定的布局中，便于多任务处理。</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"Oobe_FileLocksmith.Description\" xml:space=\"preserve\">\n    <value>快速寻找文件被哪些程序占用，一键关闭占用文件的罪魁祸首。</value>\n  </data>\n  <data name=\"Oobe_FileExplorer.Description\" xml:space=\"preserve\">\n    <value>Windows 文件资源管理器的增强组件，支持预览文档 (.md .pdf)、矢量图 (.svg)、3D 模型 (.stl .gcode) 和程序代码文件等，也为一些文件增加了缩略图的支持。</value>\n  </data>\n  <data name=\"Oobe_ImageResizer.Description\" xml:space=\"preserve\">\n    <value>使用图像裁剪器，可以方便地批量调整图像大小。</value>\n  </data>\n  <data name=\"Oobe_KBM.Description\" xml:space=\"preserve\">\n    <value>键盘修改器让你重新定义键盘按键。</value>\n  </data>\n  <data name=\"Oobe_MouseWithoutBorders.Description\" xml:space=\"preserve\">\n    <value>无界鼠标，用一套外设在多台设备间无边界协作，同步内容和文件。</value>\n  </data>\n  <data name=\"Oobe_PowerRename.Description\" xml:space=\"preserve\">\n    <value>一个简单的文件重命名工具，可以自动执行文件名搜索与替换。</value>\n  </data>\n  <data name=\"Oobe_Workspaces.Description\" xml:space=\"preserve\">\n    <value>在工作区中保存一组窗口布置，下次即可一键启动所有软件并恢复窗口位置。</value>\n  </data>\n  <data name=\"Oobe_Run.Description\" xml:space=\"preserve\">\n    <value>一个趁手的启动器，通过快捷搜索来启动插件提供的丰富功能。</value>\n  </data>\n  <data name=\"Oobe_MeasureTool.Description\" xml:space=\"preserve\">\n    <value>一个像素测量小工具，帮助设计师进行屏幕布局分析。</value>\n  </data>\n  <data name=\"Oobe_ShortcutGuide.Description\" xml:space=\"preserve\">\n    <value>显示一份系统快捷键表格，展示当前可用的系统快捷操作。</value>\n  </data>\n  <data name=\"Oobe_MouseUtils.Description\" xml:space=\"preserve\">\n    <value>一系列关于鼠标的小工具。</value>\n    <comment>Mouse as in the hardware peripheral</comment>\n  </data>\n  <data name=\"Oobe_Overview.Description\" xml:space=\"preserve\">\n    <value>微软 PowerToys 是一个工具箱，可以优化 Windows 操作，提高工作效率。\n\n这里是软件入门指南，在此可以快速了解各个功能。</value>\n  </data>\n  <data name=\"Oobe_Overview_DescriptionLinkText.Text\" xml:space=\"preserve\">\n    <value>学习在线帮助文档</value>\n  </data>\n  <data name=\"Oobe_Overview_Telemetry_Title.Text\" xml:space=\"preserve\">\n    <value>帮助我们改进 PowerToys</value>\n  </data>\n  <data name=\"Oobe_Overview_Telemetry_Desc.Text\" xml:space=\"preserve\">\n    <value>通过收集和分析软件的运行状况，我们可以让它更加安全稳定。</value>\n  </data>\n  <data name=\"Oobe_Overview_DiagnosticsAndFeedback_Settings_Link.Content\" xml:space=\"preserve\">\n    <value>诊断数据设置</value>\n  </data>\n  <data name=\"Oobe_Overview_DiagnosticsAndFeedback_Link.Content\" xml:space=\"preserve\">\n    <value>详细了解我们收集的信息及其用途</value>\n  </data>\n  <data name=\"Oobe_Overview_EnableDataDiagnostics.Header\" xml:space=\"preserve\">\n    <value>发送诊断数据</value>\n  </data>\n  <data name=\"Oobe_Overview_EnableDataDiagnostics.Description\" xml:space=\"preserve\">\n    <value>帮助我们找到错误、优化性能、调整开发方向</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_InfoBar.Header\" xml:space=\"preserve\">\n    <value>您愿意发送诊断数据来帮助我们改进 PowerToys 吗？</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_InfoBar_Desc.Text\" xml:space=\"preserve\">\n    <value>该功能完全由您自主选择是否开启</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_InfoBar_Button_Enable.Content\" xml:space=\"preserve\">\n    <value>启用</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_Yes_Click_InfoBar_Title\" xml:space=\"preserve\">\n    <value>感谢您的参与，让 PowerToys 更加出色！</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_No_Click_InfoBar_Title\" xml:space=\"preserve\">\n    <value>设置成功</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_Yes_Click_InfoBar_Desc.Text\" xml:space=\"preserve\">\n    <value>如果需要关闭的话，可以前往 </value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_Yes_Click_OpenSettings_Text.Text\" xml:space=\"preserve\">\n    <value>设置页面</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_Button_Yes.Content\" xml:space=\"preserve\">\n    <value>好呀</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DataDiagnostics_Button_No.Content\" xml:space=\"preserve\">\n    <value>不要</value>\n  </data>\n  <data name=\"ReleaseNotes.Content\" xml:space=\"preserve\">\n    <value>版本公告</value>\n  </data>\n  <data name=\"Oobe_ColorPicker_HowToUse.Text\" xml:space=\"preserve\">\n    <value>启动取色器。</value>\n  </data>\n  <data name=\"Oobe_ColorPicker_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>可以 **滚动鼠标滚轮** 来放大，方便精细观察。</value>\n  </data>\n  <data name=\"Oobe_FancyZones_HowToUse.Text\" xml:space=\"preserve\">\n    <value>按住 **Shift** 同时 **拖动窗口** ，可将窗口贴靠到一个布局区。</value>\n  </data>\n  <data name=\"Oobe_FancyZones_HowToUse_Shortcut.Text\" xml:space=\"preserve\">\n    <value>打开布局编辑器。</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"Oobe_FancyZones_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>按住 **Shift** + **Ctrl** 拖动窗口，可将窗口贴靠到多个布局区拼接。</value>\n  </data>\n  <data name=\"Oobe_FileLocksmith_HowToUse.Text\" xml:space=\"preserve\">\n    <value>选中要解除占用的文件，单击 **右键**，然后在右键菜单中选择 **查看文件占用** 。</value>\n  </data>\n  <data name=\"Oobe_FileLocksmith_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>点击右上角管理员权限按钮，获取更高权限来查看更多程序的占用情况。</value>\n  </data>\n  <data name=\"Oobe_FileExplorer_HowToEnable.Text\" xml:space=\"preserve\">\n    <value>打开文件资源管理器，在顶部的工具栏中选择 **查看** 选项卡，然后选择 **查看** 中的 **预览窗格** 来启用预览功能。\n然后，试试选中一个 PDF 文档或程序代码，在预览窗格中成功查看了文件内容！</value>\n  </data>\n  <data name=\"Oobe_HowToCreateMappings.Text\" xml:space=\"preserve\">\n    <value>如何创建映射</value>\n  </data>\n  <data name=\"Oobe_HowToEnable.Text\" xml:space=\"preserve\">\n    <value>如何启用</value>\n  </data>\n  <data name=\"Oobe_HowToLaunch.Text\" xml:space=\"preserve\">\n    <value>如何启动</value>\n  </data>\n  <data name=\"Oobe_HowToUse.Text\" xml:space=\"preserve\">\n    <value>如何使用</value>\n  </data>\n  <data name=\"Oobe_ImageResizer_HowToLaunch.Text\" xml:space=\"preserve\">\n    <value>选中几个图片，单击 **右键** ，然后在右键菜单中选择 **调整图片大小** 。</value>\n  </data>\n  <data name=\"Oobe_ImageResizer_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>三种操作方式的差别：\n填充：按比例调整到目标尺寸上，填满整个空间，多余部分裁掉。\n缩放：按比例调整到目标尺寸内，保持图像完整，剩下空间留白。\n拉伸：忽略长宽比例，完全按照目标尺寸拉伸，可能导致图形压缩变形。\n\n除了预设的几种尺寸，在设置里你也可以添加常用的自定义尺寸。</value>\n  </data>\n  <data name=\"Oobe_KBM_HowToCreateMappings.Text\" xml:space=\"preserve\">\n    <value>打开 **设置** ，在键盘修改器菜单中，选择 **重映射单键** 或 **重映射组合键** 。</value>\n  </data>\n  <data name=\"Oobe_KBM_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>想要只对某个应用生效的快捷键？创建快捷键重映射时，可以指定“目标程序”。</value>\n  </data>\n  <data name=\"Oobe_MouseWithoutBorders_HowToUse.Text\" xml:space=\"preserve\">\n    <value>记住这台电脑的名称和密码，然后在别的电脑的无界鼠标 **连接** 菜单中输入，建立连接。\n如果连不上，试试 **添加防火墙允许规则**。\n想要清除连接的话，只需要重新生成一次密码即可。</value>\n  </data>\n  <data name=\"Oobe_MouseWithoutBorders_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>在电脑上安装无界鼠标服务可以取得更高控制权，即使电脑锁屏了也可以被控制，记住不要轻易告诉别人密码哦。</value>\n  </data>\n  <data name=\"Oobe_PowerRename_HowToUse.Text\" xml:space=\"preserve\">\n    <value>选中几个文件，单击 **右键** ，然后在右键菜单中选择 **批量重命名** 。</value>\n  </data>\n  <data name=\"Oobe_Workspaces_HowToUse_Shortcut.Text\" xml:space=\"preserve\">\n    <value>打开工作区编辑器。</value>\n    <comment>{Locked=\"Workspaces\"}</comment>\n  </data>\n  <data name=\"Oobe_Workspaces_HowToUse.Text\" xml:space=\"preserve\">\n    <value>在工作区编辑器中可以创建一个工作区——也就是一组按照特定布局排列的软件窗口。之后，您可以在编辑器中启动工作区，恢复所有打开的窗口，也可以创建一个桌面快捷方式来启动它。</value>\n  </data>\n  <data name=\"Oobe_Workspaces_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>如果需要让工作区内的软件，在启动后自动打开某个文件、恢复上次的编辑状态，您可能需要添加一些命令行参数。</value>\n  </data>\n  <data name=\"Oobe_PowerRename_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>可以使用正则表达式，进行高级操作。</value>\n  </data>\n  <data name=\"Oobe_Run_HowToLaunch.Text\" xml:space=\"preserve\">\n    <value>启动快捷启动器，随意搜点什么吧~</value>\n  </data>\n  <data name=\"Oobe_Run_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>快捷启动器支持各种唤醒词，以搜索特定的结果。\n\n例如，输入 `&lt;` 搜索运行中的程序进程，输入 `?` 搜索文件，输入 `.` 搜索已安装的应用。\n\n如果想要学习所有能用的唤醒词，请阅读在线帮助文档。</value>\n  </data>\n  <data name=\"Oobe_ShortcutGuide_HowToLaunch.Text\" xml:space=\"preserve\">\n    <value>显示快捷键指南，再按一次或按 **Esc** 关闭。（也可设置为长按 Win 键显示）</value>\n  </data>\n  <data name=\"Oobe_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>小技巧</value>\n  </data>\n  <data name=\"Oobe_MeasureTool_Activation.Text\" xml:space=\"preserve\">\n    <value>打开标尺栏。</value>\n  </data>\n  <data name=\"Oobe_MeasureTool_HowToLaunch.Text\" xml:space=\"preserve\">\n    <value>在标尺栏中选择所需模式。\n\n框选模式：拖动选中一块测量选区尺寸，按住 **Shift** 保留选区，**右键** 清空。\n\n间距模式：轴向测量颜色相近像素长度，容差可在设置里设定。</value>\n  </data>\n  <data name=\"Oobe_MeasureTool.Title\" xml:space=\"preserve\">\n    <value>屏幕标尺</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_ColorPicker.Title\" xml:space=\"preserve\">\n    <value>取色器</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_FancyZones.Title\" xml:space=\"preserve\">\n    <value>窗口布局</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"Oobe_FileLocksmith.Title\" xml:space=\"preserve\">\n    <value>文件开锁匠</value>\n  </data>\n  <data name=\"Oobe_ImageResizer.Title\" xml:space=\"preserve\">\n    <value>图像裁剪器</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_KBM.Title\" xml:space=\"preserve\">\n    <value>键盘修改器</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_MouseWithoutBorders.Title\" xml:space=\"preserve\">\n    <value>无界鼠标</value>\n    <comment>Product name. Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_PowerRename.Title\" xml:space=\"preserve\">\n    <value>批量重命名</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_Workspaces.Title\" xml:space=\"preserve\">\n    <value>工作区</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_Run.Title\" xml:space=\"preserve\">\n    <value>快捷启动器</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_ShortcutGuide.Title\" xml:space=\"preserve\">\n    <value>快捷键指南</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_Overview.Title\" xml:space=\"preserve\">\n    <value>初次见面</value>\n  </data>\n  <data name=\"Oobe_WhatsNew.Text\" xml:space=\"preserve\">\n    <value>更新日志</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_LoadingError.Title\" xml:space=\"preserve\">\n    <value>无法加载更新日志。</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_LoadingError.Message\" xml:space=\"preserve\">\n    <value>请检查网络连接。</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_ProxyAuthenticationWarning.Title\" xml:space=\"preserve\">\n    <value>无法加载更新日志。</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_ProxyAuthenticationWarning.Message\" xml:space=\"preserve\">\n    <value>您的代理服务器需要身份验证。</value>\n  </data>\n  <data name=\"Oobe_WhatsNew_DetailedReleaseNotesLink.Text\" xml:space=\"preserve\">\n    <value>访问我们的 GitHub 仓库以查看详细记录</value>\n    <comment>Don't loc \"GitHub\", it's the name of a product</comment>\n  </data>\n  <data name=\"OOBE_Settings.Content\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"Oobe_NavViewItem.Content\" xml:space=\"preserve\">\n    <value>入门指南</value>\n    <comment>Don't loc \"PowerToys\"</comment>\n  </data>\n  <data name=\"WhatIsNew_NavViewItem.Content\" xml:space=\"preserve\">\n    <value>更新日志</value>\n  </data>\n  <data name=\"Feedback_NavViewItem.Content\" xml:space=\"preserve\">\n    <value>问题反馈</value>\n  </data>\n  <data name=\"OobeWindow_Title\" xml:space=\"preserve\">\n    <value>PowerToys 入门指南</value>\n  </data>\n  <data name=\"OobeWindow_TitleTxt.Text\" xml:space=\"preserve\">\n    <value>PowerToys 入门指南</value>\n  </data>\n  <data name=\"SettingsWindow_Title\" xml:space=\"preserve\">\n    <value>PowerToys 设置</value>\n    <comment>Title of the settings window when running as user</comment>\n  </data>\n  <data name=\"Awake.ModuleTitle\" xml:space=\"preserve\">\n    <value>阻止睡眠</value>\n  </data>\n  <data name=\"Awake.ModuleDescription\" xml:space=\"preserve\">\n    <value>轻松保持电脑活力。</value>\n  </data>\n  <data name=\"Awake_EnableSettingsCard.Header\" xml:space=\"preserve\">\n    <value>启用阻止睡眠工具</value>\n    <comment>Awake is a product name, do not loc</comment>\n  </data>\n  <data name=\"Awake_NoKeepAwakeSelector.Content\" xml:space=\"preserve\">\n    <value>关闭</value>\n  </data>\n  <data name=\"Awake_IndefiniteKeepAwakeSelector.Content\" xml:space=\"preserve\">\n    <value>无限模式</value>\n  </data>\n  <data name=\"Awake_TemporaryKeepAwakeSelector.Content\" xml:space=\"preserve\">\n    <value>倒计时模式</value>\n  </data>\n  <data name=\"Awake_ExpirableKeepAwakeSelector.Content\" xml:space=\"preserve\">\n    <value>定时关闭模式</value>\n  </data>\n  <data name=\"Awake_DisplaySettingsCard.Header\" xml:space=\"preserve\">\n    <value>保持屏幕常亮</value>\n  </data>\n  <data name=\"Awake_DisplaySettingsCard.Description\" xml:space=\"preserve\">\n    <value>需要打开阻止睡眠功能</value>\n  </data>\n  <data name=\"Awake_ExpirationSettingsExpander.Description\" xml:space=\"preserve\">\n    <value>阻止电脑睡眠，直到设定的结束时间</value>\n  </data>\n  <data name=\"Awake_ModeSettingsCard.Header\" xml:space=\"preserve\">\n    <value>模式</value>\n  </data>\n  <data name=\"Awake_BehaviorSettingsGroup.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"Awake_IntervalHoursInput.Header\" xml:space=\"preserve\">\n    <value>小时</value>\n  </data>\n  <data name=\"Awake_IntervalMinutesInput.Header\" xml:space=\"preserve\">\n    <value>分钟</value>\n  </data>\n  <data name=\"Awake_ExpirationSettingsExpander_Date.Header\" xml:space=\"preserve\">\n    <value>结束日期</value>\n  </data>\n  <data name=\"Awake_ExpirationSettingsExpander_Time.Header\" xml:space=\"preserve\">\n    <value>结束时间</value>\n  </data>\n  <data name=\"Oobe_Awake.Title\" xml:space=\"preserve\">\n    <value>阻止睡眠</value>\n    <comment>Module name, do not loc</comment>\n  </data>\n  <data name=\"Oobe_Awake.Description\" xml:space=\"preserve\">\n    <value>阻止睡眠工具可以在后台阻止电脑自动锁屏或者睡眠，防止电脑执行特别耗时的任务时中断，免去了手动修改电源设置的麻烦。</value>\n  </data>\n  <data name=\"Oobe_Awake_HowToUse.Text\" xml:space=\"preserve\">\n    <value>打开 **设置** ，启用阻止睡眠工具。</value>\n  </data>\n  <data name=\"Oobe_Awake_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>你可以 **右键状态栏的蓝色杯子图标** 来切换模式。</value>\n  </data>\n  <data name=\"General_FailedToDownloadTheNewVersion.Title\" xml:space=\"preserve\">\n    <value>版本更新出错:</value>\n  </data>\n  <data name=\"General_InstallNow.Content\" xml:space=\"preserve\">\n    <value>立刻安装</value>\n  </data>\n  <data name=\"General_ReadMore.Text\" xml:space=\"preserve\">\n    <value>了解详情</value>\n  </data>\n  <data name=\"General_NewVersionAvailable.Title\" xml:space=\"preserve\">\n    <value>有版本更新:</value>\n  </data>\n  <data name=\"General_Downloading.Text\" xml:space=\"preserve\">\n    <value>下载中...</value>\n  </data>\n  <data name=\"General_TryAgainToDownloadAndInstall.Content\" xml:space=\"preserve\">\n    <value>重新下载并安装</value>\n  </data>\n  <data name=\"General_CheckingForUpdates.Text\" xml:space=\"preserve\">\n    <value>正在检查更新...</value>\n  </data>\n  <data name=\"General_NewVersionReadyToInstall.Title\" xml:space=\"preserve\">\n    <value>更新等待安装:</value>\n  </data>\n  <data name=\"General_UpToDate.Title\" xml:space=\"preserve\">\n    <value>已是最新版本</value>\n  </data>\n  <data name=\"General_CantCheck.Title\" xml:space=\"preserve\">\n    <value>网络错误，请稍后再试</value>\n  </data>\n  <data name=\"General_DownloadAndInstall.Content\" xml:space=\"preserve\">\n    <value>下载并安装</value>\n  </data>\n  <data name=\"ImageResizer_Fit_Fill_ThirdPersonSingular\" xml:space=\"preserve\">\n    <value>填充到</value>\n  </data>\n  <data name=\"ImageResizer_Fit_Fit_ThirdPersonSingular\" xml:space=\"preserve\">\n    <value>缩放到</value>\n  </data>\n  <data name=\"ImageResizer_Fit_Stretch_ThirdPersonSingular\" xml:space=\"preserve\">\n    <value>拉伸到</value>\n  </data>\n  <data name=\"ImageResizer_Unit_Centimeter\" xml:space=\"preserve\">\n    <value>厘米</value>\n  </data>\n  <data name=\"ImageResizer_Unit_Inch\" xml:space=\"preserve\">\n    <value>英寸</value>\n  </data>\n  <data name=\"ImageResizer_Unit_Percent\" xml:space=\"preserve\">\n    <value>%</value>\n  </data>\n  <data name=\"ImageResizer_Unit_Pixel\" xml:space=\"preserve\">\n    <value>像素</value>\n  </data>\n  <data name=\"ImageResizer_EditButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"ImageResizer_EditSize.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"ImageResizer_Presets.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>图像裁剪器预设</value>\n  </data>\n  <data name=\"ImageResizer_AddSizeButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>添加预设</value>\n  </data>\n  <data name=\"ImageResizer_RemoveButton.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"ImageResizer_EditButton_Accessibility_Name\" xml:space=\"preserve\">\n    <value>编辑预设 {0}</value>\n    <comment>Expands to the AutomationProperties.Name value for the Edit button. Example: \"Edit the Small preset\".</comment>\n  </data>\n  <data name=\"ImageResizer_RemoveButton_Accessibility_Name\" xml:space=\"preserve\">\n    <value>删除预设 {0}</value>\n    <comment>Expands to the AutomationProperties.Name value for the Remove button. Example: \"Remove the Large preset\".</comment>\n  </data>\n  <data name=\"No\" xml:space=\"preserve\">\n    <value>否</value>\n    <comment>Label of a cancel button</comment>\n  </data>\n  <data name=\"Delete_Dialog_Description\" xml:space=\"preserve\">\n    <value>确认删除此项吗？</value>\n  </data>\n  <data name=\"Yes\" xml:space=\"preserve\">\n    <value>是</value>\n    <comment>Label of a confirmation button</comment>\n  </data>\n  <data name=\"SeeWhatsNew.Content\" xml:space=\"preserve\">\n    <value>更新日志</value>\n  </data>\n  <data name=\"Awake_ModeSettingsCard.Description\" xml:space=\"preserve\">\n    <value>设置阻止睡眠模式</value>\n  </data>\n  <data name=\"ExcludedApps.Header\" xml:space=\"preserve\">\n    <value>忽略应用</value>\n  </data>\n  <data name=\"Enable_ColorFormat.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>启用颜色格式</value>\n  </data>\n  <data name=\"More_Options_Button.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>更多选项</value>\n  </data>\n  <data name=\"More_Options_ButtonTooltip.Text\" xml:space=\"preserve\">\n    <value>更多</value>\n  </data>\n  <data name=\"To.Text\" xml:space=\"preserve\">\n    <value>映射</value>\n    <comment>as in: from x to y</comment>\n  </data>\n  <data name=\"Starts.Text\" xml:space=\"preserve\">\n    <value>运行</value>\n    <comment>as in: doing x will start y</comment>\n  </data>\n  <data name=\"LearnMore_Awake.Text\" xml:space=\"preserve\">\n    <value>详细了解阻止睡眠工具</value>\n    <comment>Awake is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_CmdNotFound.Text\" xml:space=\"preserve\">\n    <value>详细了解未找到命令模块</value>\n    <comment> Command Not Found is the name of the module. </comment>\n  </data>\n  <data name=\"SecondaryLink_Awake.Text\" xml:space=\"preserve\">\n    <value>Den Delimarsky 开发了该功能</value>\n    <comment>Awake is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_ColorPicker.Text\" xml:space=\"preserve\">\n    <value>详细了解取色器</value>\n    <comment>Color Picker is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_FancyZones.Text\" xml:space=\"preserve\">\n    <value>详细了解窗口布局</value>\n    <comment>{Locked=\"FancyZones\"}</comment>\n  </data>\n  <data name=\"LearnMore_FileLocksmith.Text\" xml:space=\"preserve\">\n    <value>详细了解文件开锁匠</value>\n  </data>\n  <data name=\"LearnMore_ImageResizer.Text\" xml:space=\"preserve\">\n    <value>详细了解图像裁剪器</value>\n    <comment>Image Resizer is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_KBM.Text\" xml:space=\"preserve\">\n    <value>详细了解键盘修改器</value>\n    <comment>Keyboard Manager is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_MouseUtils.Text\" xml:space=\"preserve\">\n    <value>详细了解鼠标工具箱</value>\n    <comment>Mouse utilities is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_AdvancedPaste.Text\" xml:space=\"preserve\">\n    <value>详细了解高级粘贴</value>\n    <comment> Advanced Paste is the name of the module. </comment>\n  </data>\n  <data name=\"LearnMore_MouseWithoutBorders.Text\" xml:space=\"preserve\">\n    <value>详细了解无界鼠标</value>\n    <comment>Mouse Without Borders is the name of the module. </comment>\n  </data>\n  <data name=\"LearnMore_PowerPreview.Text\" xml:space=\"preserve\">\n    <value>详细了解预览增强组件</value>\n    <comment>File Explorer is a product name, localize as Windows does</comment>\n  </data>\n  <data name=\"LearnMore_Peek.Text\" xml:space=\"preserve\">\n    <value>详细了解快速查看</value>\n    <comment>Peek is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_PowerRename.Text\" xml:space=\"preserve\">\n    <value>详细了解批量重命名</value>\n    <comment>PowerRename is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_Run.Text\" xml:space=\"preserve\">\n    <value>详细了解启动器</value>\n    <comment>PowerToys Run is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_MeasureTool.Text\" xml:space=\"preserve\">\n    <value>详细了解屏幕标尺</value>\n    <comment>Screen Ruler is a product name, do not loc</comment>\n  </data>\n  <data name=\"LearnMore_ShortcutGuide.Text\" xml:space=\"preserve\">\n    <value>详细了解快捷键指南</value>\n    <comment>Shortcut Guide is a product name, do not loc</comment>\n  </data>\n  <data name=\"Oobe_FileExplorer.Title\" xml:space=\"preserve\">\n    <value>预览增强</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils.Title\" xml:space=\"preserve\">\n    <value>鼠标工具箱</value>\n    <comment>Mouse as in the hardware peripheral</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_FindMyMouse.Text\" xml:space=\"preserve\">\n    <value>鼠标定位</value>\n    <comment>Mouse as in the hardware peripheral</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_FindMyMouse_Description.Text\" xml:space=\"preserve\">\n    <value>晃动鼠标或按下快捷键，在鼠标光标所在位置投下聚光灯，便于寻找光标。</value>\n    <comment>Mouse as in the hardware peripheral. Key as in a keyboard key</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_MouseHighlighter.Text\" xml:space=\"preserve\">\n    <value>鼠标高亮</value>\n    <comment>Mouse as in the hardware peripheral.</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_MouseHighlighter_Description.Text\" xml:space=\"preserve\">\n    <value>按下鼠标左键和右键，显示高亮标记，指示按键操作。</value>\n    <comment>Mouse as in the hardware peripheral.</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_MousePointerCrosshairs.Text\" xml:space=\"preserve\">\n    <value>鼠标准心</value>\n    <comment>Mouse as in the hardware peripheral.</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_MousePointerCrosshairs_Description.Text\" xml:space=\"preserve\">\n    <value>以鼠标光标为中心显示十字准线，显示鼠标位置。</value>\n    <comment>Mouse as in the hardware peripheral.</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_MouseJump.Text\" xml:space=\"preserve\">\n    <value>鼠标跳转</value>\n    <comment>Mouse as in the hardware peripheral.</comment>\n  </data>\n  <data name=\"Oobe_MouseUtils_MouseJump_Description.Text\" xml:space=\"preserve\">\n    <value>打开小地图，快速远距离移动鼠标光标。</value>\n    <comment>Mouse as in the hardware peripheral.</comment>\n  </data>\n  <data name=\"Launch_Run.Content\" xml:space=\"preserve\">\n    <value>打开快捷启动器</value>\n  </data>\n  <data name=\"Launch_ShortcutGuide.Content\" xml:space=\"preserve\">\n    <value>显示快捷键指南</value>\n  </data>\n  <data name=\"ColorPicker_ColorFormat_ToggleSwitch.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>颜色格式</value>\n  </data>\n  <data name=\"GeneralPage_Documentation.Text\" xml:space=\"preserve\">\n    <value>帮助文档</value>\n  </data>\n  <data name=\"PowerLauncher_SearchList.PlaceholderText\" xml:space=\"preserve\">\n    <value>搜索</value>\n  </data>\n  <data name=\"PowerLauncher_SearchList.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>搜索</value>\n  </data>\n  <data name=\"Awake.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"ColorPicker.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"General.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>相关信息</value>\n  </data>\n  <data name=\"ImageResizer.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"MouseUtils.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"PowerLauncher.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"PowerRename.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"EditTooltip.Text\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"RemoveTooltip.Text\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"Activation_Shortcut_Cancel\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"Activation_Shortcut_Description\" xml:space=\"preserve\">\n    <value>请按下你想要的快捷键</value>\n  </data>\n  <data name=\"Activation_Shortcut_With_Disable_Description\" xml:space=\"preserve\">\n    <value>请按下你想要的快捷键\n点击右键清除快捷键并禁用该功能</value>\n  </data>\n  <data name=\"Activation_Shortcut_Reset\" xml:space=\"preserve\">\n    <value>重置</value>\n  </data>\n  <data name=\"Activation_Shortcut_Save\" xml:space=\"preserve\">\n    <value>保存</value>\n  </data>\n  <data name=\"Activation_Shortcut_Title\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"InvalidShortcut.Title\" xml:space=\"preserve\">\n    <value>快捷键无效</value>\n  </data>\n  <data name=\"InvalidShortcutWarningLabel.Text\" xml:space=\"preserve\">\n    <value>正确的快捷键需要包含 **Win**、**Ctrl**、**Alt** 或 **Shift**</value>\n    <comment>The ** sequences are used for text formatting of the key names. Don't remove them on translation.</comment>\n  </data>\n  <data name=\"WarningShortcutAltGr.Title\" xml:space=\"preserve\">\n    <value>Ctrl + Alt 可能会干扰 Alt Gr 按键</value>\n    <comment>Alt Gr refers to the right alt key on some international keyboards</comment>\n  </data>\n  <data name=\"WarningShortcutAltGr.ToolTipService.ToolTip\" xml:space=\"preserve\">\n    <value>对于一些国际和欧洲键盘布局，设置 Ctrl + Alt 的快捷键可能会导致一些需要按住 Alt Gr 来输入的字符打不出来，因为在这些键盘上 Ctrl + Alt = Alt Gr</value>\n    <comment>The ** sequences are used for text formatting of the key names. Don't remove them on translation.  // 你他喵的格式化没开！当前版本暂时先不要**</comment>\n  </data>\n  <data name=\"FancyZones_SpanZonesAcrossMonitors.Description\" xml:space=\"preserve\">\n    <value>显示器的缩放比例需相同，且将视作一整个长方形</value>\n  </data>\n  <data name=\"ImageResizer_DefaultSize_NewSizePrefix\" xml:space=\"preserve\">\n    <value>新建预设</value>\n    <comment>First part of the default name of new sizes that can be added in PT's settings ui.</comment>\n  </data>\n  <data name=\"Awake_IntervalSettingsCard.Header\" xml:space=\"preserve\">\n    <value>持续时间</value>\n  </data>\n  <data name=\"Awake_ExpirationSettingsExpander.Header\" xml:space=\"preserve\">\n    <value>结束时间</value>\n  </data>\n  <data name=\"MouseUtils.ModuleTitle\" xml:space=\"preserve\">\n    <value>鼠标工具箱</value>\n  </data>\n  <data name=\"MouseUtils.ModuleDescription\" xml:space=\"preserve\">\n    <value>一系列关于鼠标的小工具。</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse.Header\" xml:space=\"preserve\">\n    <value>鼠标定位</value>\n    <comment>Refers to the utility name</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse.Description\" xml:space=\"preserve\">\n    <value>以聚光灯的形式定位鼠标光标</value>\n    <comment>\"Ctrl\" is a keyboard key. \"Find My Mouse\" is the name of the utility</comment>\n  </data>\n  <data name=\"MouseUtils_Enable_FindMyMouse.Header\" xml:space=\"preserve\">\n    <value>启用鼠标定位</value>\n    <comment>\"Find My Mouse\" is the name of the utility.</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ActivationMethod.Header\" xml:space=\"preserve\">\n    <value>启动方式</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ActivationDoubleControlPress.Content\" xml:space=\"preserve\">\n    <value>双击左 Ctrl 键</value>\n    <comment>Left control is the physical key on the keyboard.</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ActivationShakeMouse.Content\" xml:space=\"preserve\">\n    <value>晃动鼠标</value>\n    <comment>Mouse is the hardware peripheral.</comment>\n  </data>\n  <data name=\"MouseUtils_Include_Win_Key.Content\" xml:space=\"preserve\">\n    <value>按住 Win 键再按快捷键启动</value>\n    <comment>Specifies that the 'Find My Mouse' will only activate if the Windows key is held down while pressing the Ctrl key twice.</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ExcludedApps.Description\" xml:space=\"preserve\">\n    <value>填写忽略应用的名称，每行一个，防止在应用中误触而显示聚光灯</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ExcludedApps.Header\" xml:space=\"preserve\">\n    <value>忽略应用</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ExcludedApps_TextBoxControl.PlaceholderText\" xml:space=\"preserve\">\n    <value>例如: outlook.exe</value>\n  </data>\n  <data name=\"MouseUtils_Prevent_Activation_On_Game_Mode.Content\" xml:space=\"preserve\">\n    <value>游戏模式中禁用</value>\n    <comment>\"Game mode\" is the Windows feature to prevent notification when playing a game.</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_BackgroundColor.Header\" xml:space=\"preserve\">\n    <value>背景颜色</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_SpotlightColor.Header\" xml:space=\"preserve\">\n    <value>聚光灯颜色</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_OverlayOpacity.Header\" xml:space=\"preserve\">\n    <value>不透明度（%）</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_SpotlightRadius.Header\" xml:space=\"preserve\">\n    <value>聚光灯半径（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_SpotlightInitialZoom.Header\" xml:space=\"preserve\">\n    <value>聚光灯凝聚量</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_SpotlightInitialZoom.Description\" xml:space=\"preserve\">\n    <value>聚光灯汇聚、发散的大小</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_AnimationDurationMs.Header\" xml:space=\"preserve\">\n    <value>动画持续时间（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_AnimationDurationMs.Description\" xml:space=\"preserve\">\n    <value>聚光灯出现、消失的时长</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_AnimationDurationMs_Disabled.Title\" xml:space=\"preserve\">\n    <value>动画效果已被系统禁用</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ShakingMinimumDistance.Header\" xml:space=\"preserve\">\n    <value>晃动距离</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ShakingMinimumDistance.Description\" xml:space=\"preserve\">\n    <value>晃动鼠标的最小激活距离</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ShakingIntervalMs.Header\" xml:space=\"preserve\">\n    <value>晃动时长（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ShakingIntervalMs.Description\" xml:space=\"preserve\">\n    <value>晃动鼠标的最大时间跨度</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ShakingFactor.Header\" xml:space=\"preserve\">\n    <value>晃动比例（%）</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ShakingFactor.Description\" xml:space=\"preserve\">\n    <value>晃动比例=鼠标轨迹长度÷移动范围对角线，减少判定比例可提高敏感度</value>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter.Header\" xml:space=\"preserve\">\n    <value>鼠标高亮</value>\n    <comment>Refers to the utility name</comment>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter.Description\" xml:space=\"preserve\">\n    <value>高亮突出鼠标动作</value>\n    <comment>\"Mouse Highlighter\" is the name of the utility. Mouse is the hardware mouse.</comment>\n  </data>\n  <data name=\"MouseUtils_Enable_MouseHighlighter.Header\" xml:space=\"preserve\">\n    <value>启用鼠标高亮</value>\n    <comment>\"Find My Mouse\" is the name of the utility.</comment>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_ActivationShortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_ActivationShortcut.Description\" xml:space=\"preserve\">\n    <value>打开高亮的快捷键</value>\n    <comment>\"Mouse Highlighter\" is the name of the utility. Mouse is the hardware mouse.</comment>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_PrimaryButtonClickColor.Header\" xml:space=\"preserve\">\n    <value>左键颜色</value>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_SecondaryButtonClickColor.Header\" xml:space=\"preserve\">\n    <value>右键颜色</value>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_HighlightRadius.Header\" xml:space=\"preserve\">\n    <value>半径（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_FadeDelayMs.Header\" xml:space=\"preserve\">\n    <value>消失延迟（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_FadeDelayMs.Description\" xml:space=\"preserve\">\n    <value>高亮开始消失的时间</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_FadeDurationMs.Header\" xml:space=\"preserve\">\n    <value>消失时长（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_FadeDurationMs.Description\" xml:space=\"preserve\">\n    <value>高亮消失所用的时间</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs.Header\" xml:space=\"preserve\">\n    <value>鼠标准心</value>\n    <comment>Refers to the utility name</comment>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs.Description\" xml:space=\"preserve\">\n    <value>以鼠标光标为中心显示十字准线</value>\n    <comment>\"Mouse Pointer Crosshairs\" is the name of the utility. Mouse is the hardware mouse.</comment>\n  </data>\n  <data name=\"MouseUtils_Enable_MousePointerCrosshairs.Header\" xml:space=\"preserve\">\n    <value>启用鼠标准心</value>\n    <comment>\"Mouse Pointer Crosshairs\" is the name of the utility.</comment>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_ActivationShortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_ActivationShortcut.Description\" xml:space=\"preserve\">\n    <value>打开准心的快捷键</value>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsColor.Header\" xml:space=\"preserve\">\n    <value>线条颜色</value>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsOpacity.Header\" xml:space=\"preserve\">\n    <value>不透明度（%）</value>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsRadius.Header\" xml:space=\"preserve\">\n    <value>中心半径（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsThickness.Header\" xml:space=\"preserve\">\n    <value>线条厚度（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsBorderColor.Header\" xml:space=\"preserve\">\n    <value>边框颜色</value>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsBorderSize.Header\" xml:space=\"preserve\">\n    <value>边框厚度（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_IsCrosshairsFixedLengthEnabled.Header\" xml:space=\"preserve\">\n    <value>线条长度有限</value>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsFixedLength.Header\" xml:space=\"preserve\">\n    <value>线条长度（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"FancyZones_Radio_Custom_Colors.Content\" xml:space=\"preserve\">\n    <value>自定义</value>\n  </data>\n  <data name=\"FancyZones_Radio_Default_Theme.Content\" xml:space=\"preserve\">\n    <value>跟随系统</value>\n  </data>\n  <data name=\"ColorModeHeader.Header\" xml:space=\"preserve\">\n    <value>主题颜色</value>\n  </data>\n  <data name=\"FancyZones_Zone_Appearance.Description\" xml:space=\"preserve\">\n    <value>调整布局的外观</value>\n  </data>\n  <data name=\"FancyZones_Zone_Appearance.Header\" xml:space=\"preserve\">\n    <value>布局外观</value>\n  </data>\n  <data name=\"LearnMore.Content\" xml:space=\"preserve\">\n    <value>查看</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_GCODE.Header\" xml:space=\"preserve\">\n    <value>数控指令</value>\n    <comment>File type, do not translate</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Thumbnail_GCODE.Description\" xml:space=\"preserve\">\n    <value>附带缩略图的 .gcode</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_GCODE.Header\" xml:space=\"preserve\">\n    <value>数控指令</value>\n    <comment>File type, do not translate</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Preview_GCODE.Description\" xml:space=\"preserve\">\n    <value>附带缩略图的 .gcode</value>\n  </data>\n  <data name=\"FancyZones_NumberColor.Header\" xml:space=\"preserve\">\n    <value>编号颜色</value>\n  </data>\n  <data name=\"FancyZones_ShowZoneNumberCheckBoxControl.Content\" xml:space=\"preserve\">\n    <value>显示布局区编号</value>\n  </data>\n  <data name=\"ToggleSwitch.OffContent\" xml:space=\"preserve\">\n    <value>关</value>\n    <comment>The state of a ToggleSwitch when it's off</comment>\n  </data>\n  <data name=\"ToggleSwitch.OnContent\" xml:space=\"preserve\">\n    <value>开</value>\n    <comment>The state of a ToggleSwitch when it's on</comment>\n  </data>\n  <data name=\"CropAndLock.ModuleDescription\" xml:space=\"preserve\">\n    <value>实时截取所选窗口的一小块</value>\n    <comment>\"Crop And Lock\" is the name of the utility</comment>\n  </data>\n  <data name=\"CropAndLock.ModuleTitle\" xml:space=\"preserve\">\n    <value>窗口镜像</value>\n    <comment>\"Crop And Lock\" is the name of the utility</comment>\n  </data>\n  <data name=\"CropAndLock_Activation_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"CropAndLock_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用窗口镜像</value>\n    <comment>\"Crop And Lock\" is the name of the utility</comment>\n  </data>\n  <data name=\"Shell_CropAndLock.Content\" xml:space=\"preserve\">\n    <value>窗口镜像</value>\n    <comment>\"Crop And Lock\" is the name of the utility</comment>\n  </data>\n  <data name=\"LearnMore_CropAndLock.Text\" xml:space=\"preserve\">\n    <value>详细了解窗口镜像</value>\n    <comment>\"Crop And Lock\" is the name of the utility</comment>\n  </data>\n  <data name=\"CropAndLock_ReparentActivation_Shortcut.Header\" xml:space=\"preserve\">\n    <value>重定向窗口</value>\n  </data>\n  <data name=\"CropAndLock_ReparentActivation_Shortcut.Description\" xml:space=\"preserve\">\n    <value>通过重定向来截取窗口的一部分，可以控制窗口，可能造成窗口出错</value>\n  </data>\n  <data name=\"CropAndLock_ThumbnailActivation_Shortcut.Header\" xml:space=\"preserve\">\n    <value>投影窗口</value>\n  </data>\n  <data name=\"CropAndLock_ThumbnailActivation_Shortcut.Description\" xml:space=\"preserve\">\n    <value>弹出新窗口，实时投影所选窗口的一部分画面，不可控制但兼容性更好</value>\n  </data>\n  <data name=\"CropAndLock.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"Oobe_CropAndLock.Title\" xml:space=\"preserve\">\n    <value>窗口镜像</value>\n    <comment>\"Crop And Lock\" is the name of the utility</comment>\n  </data>\n  <data name=\"Oobe_CropAndLock.Description\" xml:space=\"preserve\">\n    <value>从当前窗口截取一小块，创建镜像显示窗口</value>\n    <comment>\"Crop And Lock\" is the name of the utility</comment>\n  </data>\n  <data name=\"Oobe_CropAndLock_HowToUse_Thumbnail.Text\" xml:space=\"preserve\">\n    <value>弹出新窗口，实时投影所选窗口的一部分，镜像只能显示不能交互，兼容性更好</value>\n  </data>\n  <data name=\"Oobe_CropAndLock_HowToUse_Reparent.Text\" xml:space=\"preserve\">\n    <value>修改原窗口，通过重定向父级窗口截取窗口的一部分，可以交互但兼容性差</value>\n  </data>\n  <data name=\"AlwaysOnTop.ModuleDescription\" xml:space=\"preserve\">\n    <value>一键置顶当前窗口。</value>\n    <comment>{Locked=\"Always On Top\"}</comment>\n  </data>\n  <data name=\"AlwaysOnTop.ModuleTitle\" xml:space=\"preserve\">\n    <value>窗口置顶</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"AlwaysOnTop_Activation_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"Peek_Activation_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"AlwaysOnTop_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用窗口置顶</value>\n    <comment>{Locked=\"Always On Top\"}</comment>\n  </data>\n  <data name=\"AlwaysOnTop_ExcludedApps.Description\" xml:space=\"preserve\">\n    <value>填写忽略应用的名称，每行一个，这些应用程序将不会被置顶</value>\n  </data>\n  <data name=\"AlwaysOnTop_ExcludedApps.Header\" xml:space=\"preserve\">\n    <value>忽略应用列表</value>\n  </data>\n  <data name=\"AlwaysOnTop_ExcludedApps_TextBoxControl.PlaceholderText\" xml:space=\"preserve\">\n    <value>例如: outlook.exe</value>\n  </data>\n  <data name=\"AlwaysOnTop_FrameColor.Header\" xml:space=\"preserve\">\n    <value>自定义颜色</value>\n  </data>\n  <data name=\"AlwaysOnTop_FrameEnabled.Header\" xml:space=\"preserve\">\n    <value>窗口轮廓线</value>\n  </data>\n  <data name=\"AlwaysOnTop_FrameThickness.Header\" xml:space=\"preserve\">\n    <value>厚度（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"AlwaysOnTop_Behavior_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"Shell_AlwaysOnTop.Content\" xml:space=\"preserve\">\n    <value>窗口置顶</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"AlwaysOnTop_GameMode.Content\" xml:space=\"preserve\">\n    <value>游戏模式中禁用</value>\n    <comment>Game Mode is a Windows feature</comment>\n  </data>\n  <data name=\"AlwaysOnTop_SoundTitle.Header\" xml:space=\"preserve\">\n    <value>提示音</value>\n  </data>\n  <data name=\"AlwaysOnTop_Sound.Content\" xml:space=\"preserve\">\n    <value>播放操作提示音</value>\n  </data>\n  <data name=\"AlwaysOnTop_Behavior.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"LearnMore_AlwaysOnTop.Text\" xml:space=\"preserve\">\n    <value>详细了解窗口置顶</value>\n    <comment>{Locked=\"Always On Top\"}</comment>\n  </data>\n  <data name=\"AlwaysOnTop_ActivationShortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"AlwaysOnTop_ActivationShortcut.Description\" xml:space=\"preserve\">\n    <value>置顶窗口的快捷键</value>\n  </data>\n  <data name=\"Oobe_AlwaysOnTop.Title\" xml:space=\"preserve\">\n    <value>窗口置顶</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"Oobe_AlwaysOnTop.Description\" xml:space=\"preserve\">\n    <value>窗口置顶工具可以一键固定窗口到顶层，显示在其他窗口之上，优化你的多任务工作流程。</value>\n    <comment>{Locked=\"Always On Top\"}</comment>\n  </data>\n  <data name=\"Oobe_AlwaysOnTop_HowToUse.Text\" xml:space=\"preserve\">\n    <value>置顶和取消置顶当前窗口。</value>\n  </data>\n  <data name=\"Oobe_AlwaysOnTop_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>在设置里可以调整置顶窗口的轮廓线。</value>\n  </data>\n  <data name=\"AlwaysOnTop_FrameColor_Mode.Header\" xml:space=\"preserve\">\n    <value>颜色</value>\n  </data>\n  <data name=\"AlwaysOnTop_Radio_Custom_Color.Content\" xml:space=\"preserve\">\n    <value>自定义</value>\n  </data>\n  <data name=\"AlwaysOnTop_Radio_Windows_Default.Content\" xml:space=\"preserve\">\n    <value>系统主题色</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"FileExplorerPreview.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Monaco_Wrap_Text.Content\" xml:space=\"preserve\">\n    <value>自动换行</value>\n    <comment>Feature on or off</comment>\n  </data>\n  <data name=\"FancyZones_AllowPopupWindowSnap.Description\" xml:space=\"preserve\">\n    <value>对所有弹窗生效，包括系统通知</value>\n  </data>\n  <data name=\"FancyZones_AllowPopupWindowSnap.Header\" xml:space=\"preserve\">\n    <value>将弹窗纳入布局</value>\n  </data>\n  <data name=\"FancyZones_AllowChildWindowSnap.Content\" xml:space=\"preserve\">\n    <value>将子窗口纳入布局</value>\n  </data>\n  <data name=\"Shell_WhatsNew.Content\" xml:space=\"preserve\">\n    <value>更新内容</value>\n  </data>\n  <data name=\"Shell_Peek.Content\" xml:space=\"preserve\">\n    <value>快速查看</value>\n    <comment>Product name: Navigation view item name for Peek</comment>\n  </data>\n  <data name=\"Peek.ModuleTitle\" xml:space=\"preserve\">\n    <value>快速查看</value>\n  </data>\n  <data name=\"Peek.ModuleDescription\" xml:space=\"preserve\">\n    <value>选中文件按快捷键即可快速查看。</value>\n  </data>\n  <data name=\"Peek_EnablePeek.Header\" xml:space=\"preserve\">\n    <value>启用快速查看</value>\n    <comment>Peek is a product name, do not loc</comment>\n  </data>\n  <data name=\"Peek_BehaviorHeader.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"Peek_AlwaysRunNotElevated.Header\" xml:space=\"preserve\">\n    <value>始终以用户身份运行</value>\n  </data>\n  <data name=\"Peek_AlwaysRunNotElevated.Description\" xml:space=\"preserve\">\n    <value>防止不能访问网络共享文件夹，需要重开一下快速查看功能以生效</value>\n    <comment>Peek is a product name, do not loc</comment>\n  </data>\n  <data name=\"Peek_CloseAfterLosingFocus.Header\" xml:space=\"preserve\">\n    <value>失去焦点自动关闭（点击查看窗口之外就会关闭）</value>\n    <comment>Peek is a product name, do not loc</comment>\n  </data>\n  <data name=\"FancyZones_DisableRoundCornersOnWindowSnap.Content\" xml:space=\"preserve\">\n    <value>纳入布局时消除 Win11 窗口圆角</value>\n  </data>\n  <data name=\"PowerLauncher_SearchQueryTuningEnabled.Description\" xml:space=\"preserve\">\n    <value>按权重排序搜索结果</value>\n  </data>\n  <data name=\"PowerLauncher_SearchQueryTuningEnabled.Header\" xml:space=\"preserve\">\n    <value>优化排序</value>\n  </data>\n  <data name=\"PowerLauncher_SearchClickedItemWeight.Description\" xml:space=\"preserve\">\n    <value>权重越大，搜索后选中的结果下次越容易搜到，默认为 5，禁用为 0</value>\n  </data>\n  <data name=\"PowerLauncher_SearchClickedItemWeight.Header\" xml:space=\"preserve\">\n    <value>选中提升权重</value>\n  </data>\n  <data name=\"PowerLauncher_WaitForSlowResults.Description\" xml:space=\"preserve\">\n    <value>加载时开始排序，有助于选出最相关的结果，可能出现排序跳动不定</value>\n  </data>\n  <data name=\"PowerLauncher_WaitForSlowResults.Header\" xml:space=\"preserve\">\n    <value>动态排序</value>\n  </data>\n  <data name=\"PowerLauncher_ShowPluginKeywords.Header\" xml:space=\"preserve\">\n    <value>唤醒词提示</value>\n  </data>\n  <data name=\"PowerLauncher_ShowPluginKeywords.Description\" xml:space=\"preserve\">\n    <value>搜索框为空时显示一些可用的插件唤醒词</value>\n  </data>\n  <data name=\"PowerLauncher_PluginWeightBoost.Description\" xml:space=\"preserve\">\n    <value>权重越大，结果排在越前面，默认为 0</value>\n  </data>\n  <data name=\"PowerLauncher_PluginWeightBoost.Header\" xml:space=\"preserve\">\n    <value>全局排序权重</value>\n  </data>\n  <data name=\"AlwaysOnTop_RoundCorners.Content\" xml:space=\"preserve\">\n    <value>圆角</value>\n  </data>\n  <data name=\"LearnMore_QuickAccent.Text\" xml:space=\"preserve\">\n    <value>详细了解字母助手</value>\n    <comment>Quick Accent is a product name, do not loc</comment>\n  </data>\n  <data name=\"QuickAccent_EnableQuickAccent.Header\" xml:space=\"preserve\">\n    <value>启用字母助手</value>\n  </data>\n  <data name=\"Shell_QuickAccent.Content\" xml:space=\"preserve\">\n    <value>字母助手</value>\n  </data>\n  <data name=\"Shell_Workspaces.Content\" xml:space=\"preserve\">\n    <value>工作区</value>\n  </data>\n  <data name=\"Workspaces_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用工作区</value>\n    <comment>\"Workspaces\" is the name of the utility</comment>\n  </data>\n  <data name=\"Workspaces_Activation_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"Workspaces_ActivationShortcut.Description\" xml:space=\"preserve\">\n    <value>启动工作区编辑器的快捷键</value>\n  </data>\n  <data name=\"Workspaces_ActivationShortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"Workspaces_LaunchEditorButtonControl.Description\" xml:space=\"preserve\">\n    <value>创建和管理工作区</value>\n  </data>\n  <data name=\"Workspaces_LaunchEditorButtonControl.Header\" xml:space=\"preserve\">\n    <value>启动工作区编辑器</value>\n  </data>\n  <data name=\"LearnMore_Workspaces.Text\" xml:space=\"preserve\">\n    <value>详细了解工作区</value>\n    <comment> Workspaces is the name of the module. </comment>\n  </data>\n  <data name=\"QuickAccent.ModuleDescription\" xml:space=\"preserve\">\n    <value>用于输入带标记的特殊字母，当键盘上没有的时候特别方便。\n\n按住字母，按启动键，即可选择多种标记字母！</value>\n    <comment>key refers to a physical key on a keyboard</comment>\n  </data>\n  <data name=\"QuickAccent.ModuleTitle\" xml:space=\"preserve\">\n    <value>字母助手</value>\n  </data>\n  <data name=\"QuickAccent.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n  </data>\n  <data name=\"AlwaysOnTop_ShortDescription\" xml:space=\"preserve\">\n    <value>置顶窗口</value>\n  </data>\n  <data name=\"Awake_ShortDescription\" xml:space=\"preserve\">\n    <value>阻止电脑睡眠</value>\n  </data>\n  <data name=\"ColorPicker_ShortDescription\" xml:space=\"preserve\">\n    <value>抓取颜色</value>\n  </data>\n  <data name=\"CropAndLock_Thumbnail\" xml:space=\"preserve\">\n    <value>投影窗口</value>\n  </data>\n  <data name=\"CropAndLock_Reparent\" xml:space=\"preserve\">\n    <value>重定向窗口</value>\n  </data>\n  <data name=\"FancyZones_OpenEditor\" xml:space=\"preserve\">\n    <value>启动布局编辑器</value>\n  </data>\n  <data name=\"FileLocksmith_ShortDescription\" xml:space=\"preserve\">\n    <value>在右键菜单中解除文件占用</value>\n  </data>\n  <data name=\"FindMyMouse_ShortDescription\" xml:space=\"preserve\">\n    <value>聚光灯</value>\n  </data>\n  <data name=\"ImageResizer_ShortDescription\" xml:space=\"preserve\">\n    <value>在右键菜单中裁剪图片</value>\n  </data>\n  <data name=\"MouseHighlighter_ShortDescription\" xml:space=\"preserve\">\n    <value>高亮鼠标点击</value>\n  </data>\n  <data name=\"MouseJump_ShortDescription\" xml:space=\"preserve\">\n    <value>小地图闪现</value>\n  </data>\n  <data name=\"MouseCrosshairs_ShortDescription\" xml:space=\"preserve\">\n    <value>十字准线</value>\n  </data>\n  <data name=\"MouseWithoutBorders_ShortDescription\" xml:space=\"preserve\">\n    <value>多设备共用键鼠</value>\n  </data>\n  <data name=\"AdvancedPaste_ShortDescription\" xml:space=\"preserve\">\n    <value>An AI powered tool to put your clipboard content into any format you need, focused towards developer workflows.</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAISettingsCardDescription.Text\" xml:space=\"preserve\">\n    <value>让 AI 帮助你把文本转换为指定格式，需要 OpenAI API 密钥</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAISettingsCardDescriptionLearnMore.Content\" xml:space=\"preserve\">\n    <value>了解详情</value>\n  </data>\n  <data name=\"Peek_ShortDescription\" xml:space=\"preserve\">\n    <value>预览选中文件内容</value>\n  </data>\n  <data name=\"PowerRename_ShortDescription\" xml:space=\"preserve\">\n    <value>在右键菜单中自动化重命名文件</value>\n  </data>\n  <data name=\"Run_ShortDescription\" xml:space=\"preserve\">\n    <value>打开启动器</value>\n  </data>\n  <data name=\"PowerAccent_ShortDescription\" xml:space=\"preserve\">\n    <value>输入标记字母</value>\n  </data>\n  <data name=\"RegistryPreview_ShortDescription\" xml:space=\"preserve\">\n    <value>可视化编辑注册表文件</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"ScreenRuler_ShortDescription\" xml:space=\"preserve\">\n    <value>打开标尺</value>\n  </data>\n  <data name=\"ShortcutGuide_ShortDescription\" xml:space=\"preserve\">\n    <value>显示系统快捷键表格</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"PowerOcr_ShortDescription\" xml:space=\"preserve\">\n    <value>框选截图转文字</value>\n  </data>\n  <data name=\"Dashboard_Activation\" xml:space=\"preserve\">\n    <value>启动方式</value>\n  </data>\n  <data name=\"DashboardKBMShowMappingsButton.Content\" xml:space=\"preserve\">\n    <value>显示当前重映射</value>\n  </data>\n  <data name=\"Oobe_QuickAccent.Description\" xml:space=\"preserve\">\n    <value>字母助手助您顺利打出带标记的特殊字母。</value>\n  </data>\n  <data name=\"Oobe_QuickAccent.Title\" xml:space=\"preserve\">\n    <value>字母助手</value>\n  </data>\n  <data name=\"Oobe_QuickAccent_HowToUse.Text\" xml:space=\"preserve\">\n    <value>打开 **设置**，启用字母助手。\n\n按住字母（比如 a），按一下启动快捷键（左右方向键或者空格），即可选择带标记的字母（à â á ä ã å æ）</value>\n    <comment>key refers to a physical key on a keyboard</comment>\n  </data>\n  <data name=\"QuickAccent_Activation_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>快捷键</value>\n  </data>\n  <data name=\"QuickAccent_Activation_Shortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n    <comment>key refers to a physical key on a keyboard</comment>\n  </data>\n  <data name=\"QuickAccent_Activation_Shortcut.Description\" xml:space=\"preserve\">\n    <value>按住字母后，按此键显示字母助手工具栏</value>\n    <comment>key refers to a physical key on a keyboard</comment>\n  </data>\n  <data name=\"QuickAccent_Activation_Key_Arrows.Content\" xml:space=\"preserve\">\n    <value>左右方向键</value>\n    <comment>Left/Right arrow keyboard keys</comment>\n  </data>\n  <data name=\"QuickAccent_Activation_Key_Space.Content\" xml:space=\"preserve\">\n    <value>空格</value>\n    <comment>Space is the space keyboard key</comment>\n  </data>\n  <data name=\"QuickAccent_Activation_Key_Either.Content\" xml:space=\"preserve\">\n    <value>方向键和空格</value>\n    <comment>All are keys on a keyboard</comment>\n  </data>\n  <data name=\"QuickAccent_Toolbar.Header\" xml:space=\"preserve\">\n    <value>工具栏</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition.Header\" xml:space=\"preserve\">\n    <value>工具栏位置</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_TopCenter.Content\" xml:space=\"preserve\">\n    <value>正上方</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_TopLeftCorner.Content\" xml:space=\"preserve\">\n    <value>左上角</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_TopRightCorner.Content\" xml:space=\"preserve\">\n    <value>右上角</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_BottomLeftCorner.Content\" xml:space=\"preserve\">\n    <value>左下角</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_BottomCenter.Content\" xml:space=\"preserve\">\n    <value>正下方</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_BottomRightCorner.Content\" xml:space=\"preserve\">\n    <value>右下角</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_Center.Content\" xml:space=\"preserve\">\n    <value>正中央</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_Left.Content\" xml:space=\"preserve\">\n    <value>左侧</value>\n  </data>\n  <data name=\"QuickAccent_ToolbarPosition_Right.Content\" xml:space=\"preserve\">\n    <value>右侧</value>\n  </data>\n  <data name=\"QuickAccent_Behavior.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"QuickAccent_InputTimeMs.Header\" xml:space=\"preserve\">\n    <value>长按时间（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"QuickAccent_InputTimeMs.Description\" xml:space=\"preserve\">\n    <value>按住快捷键启动工具栏所需的持续时间</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"QuickAccent_ExcludedApps.Description\" xml:space=\"preserve\">\n    <value>填写忽略应用的名称，每行一个，防止在应用中误触而弹出字母助手</value>\n  </data>\n  <data name=\"QuickAccent_ExcludedApps.Header\" xml:space=\"preserve\">\n    <value>忽略应用列表</value>\n  </data>\n  <data name=\"QuickAccent_ExcludedApps_TextBoxControl.PlaceholderText\" xml:space=\"preserve\">\n    <value>例如: Teams.exe</value>\n  </data>\n  <data name=\"LearnMore_TextExtractor.Text\" xml:space=\"preserve\">\n    <value>详细了解文本提取工具</value>\n  </data>\n  <data name=\"TextExtractor_Cancel\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_NothingToBackup\" xml:space=\"preserve\">\n    <value>设置无变化，无需创建备份</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_NoBackupFound\" xml:space=\"preserve\">\n    <value>无备份</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_FailedToParseTime\" xml:space=\"preserve\">\n    <value>无法解析时间</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_UnknownBackupTime\" xml:space=\"preserve\">\n    <value>未知</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_UnknownBackupSource\" xml:space=\"preserve\">\n    <value>未知</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_ThisMachine\" xml:space=\"preserve\">\n    <value>此电脑</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_CurrentSettingsMatch\" xml:space=\"preserve\">\n    <value>设置无变化</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_CurrentSettingsStatusAt\" xml:space=\"preserve\">\n    <value>当前时间</value>\n    <comment>E.g., Food was served 'at' noon.</comment>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_CurrentSettingsDiffer\" xml:space=\"preserve\">\n    <value>设置有变化</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_CurrentSettingsNoChecked\" xml:space=\"preserve\">\n    <value>检查中...</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_CurrentSettingsUnknown\" xml:space=\"preserve\">\n    <value>未知</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_NeverRestored\" xml:space=\"preserve\">\n    <value>从未还原</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_NothingToRestore\" xml:space=\"preserve\">\n    <value>设置无变化，无需还原</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_NoSettingsFilesFound\" xml:space=\"preserve\">\n    <value>找不到设置文件</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_BackupError\" xml:space=\"preserve\">\n    <value>备份失败，试试换一个备份位置</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_SettingsFormatError\" xml:space=\"preserve\">\n    <value>备份文件格式错误，请检查这份备份文件:</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_BackupComplete\" xml:space=\"preserve\">\n    <value>备份成功</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_NoBackupSyncPath\" xml:space=\"preserve\">\n    <value>未选择备份位置</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_NoBackupsFound\" xml:space=\"preserve\">\n    <value>备份不存在，无法还原</value>\n  </data>\n  <data name=\"General_SettingsBackupAndRestore_InvalidBackupLocation\" xml:space=\"preserve\">\n    <value>备份路径无效</value>\n  </data>\n  <data name=\"TextExtractor.ModuleDescription\" xml:space=\"preserve\">\n    <value>框选截图转文字。</value>\n  </data>\n  <data name=\"TextExtractor.ModuleTitle\" xml:space=\"preserve\">\n    <value>文本提取</value>\n  </data>\n  <data name=\"TextExtractor_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用文本提取工具</value>\n  </data>\n  <data name=\"TextExtractor_SupportedLanguages.Title\" xml:space=\"preserve\">\n    <value>文本提取功能由系统 OCR 识别包提供，可按需安装更多语言</value>\n  </data>\n  <data name=\"TextExtractor_UseSnippingToolWarning.Title\" xml:space=\"preserve\">\n    <value>Win11 截图工具有更好的文本提取功能，推荐用那个</value>\n  </data>\n  <data name=\"TextExtractor_SupportedLanguages_Link.Content\" xml:space=\"preserve\">\n    <value>详细了解多语言支持</value>\n  </data>\n  <data name=\"Shell_TextExtractor.Content\" xml:space=\"preserve\">\n    <value>文本提取</value>\n  </data>\n  <data name=\"Launch_TextExtractor.Content\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"Oobe_TextExtractor.Title\" xml:space=\"preserve\">\n    <value>文本提取</value>\n  </data>\n  <data name=\"Oobe_TextExtractor_HowToUse.Text\" xml:space=\"preserve\">\n    <value>启动文本提取工具，拖动框选一块文字内容，松手，文字即刻复制到剪贴板中。</value>\n  </data>\n  <data name=\"Oobe_TextExtractor_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>按住 Shift 移动选区。</value>\n  </data>\n  <data name=\"TextExtractor.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n  </data>\n  <data name=\"Oobe_TextExtractor.Description\" xml:space=\"preserve\">\n    <value>文本提取工具从屏幕上抓取一块截图，然后通过文字识别技术复制出其中的文字。</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Monaco_Try_Format.Description\" xml:space=\"preserve\">\n    <value>针对 json 和 xml，原文件不会被改动</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Monaco_Try_Format.Header\" xml:space=\"preserve\">\n    <value>格式化代码文件</value>\n  </data>\n  <data name=\"Run_ConflictingKeywordInfo.Title\" xml:space=\"preserve\">\n    <value>部分插件唤醒词与默认唤醒的插件有冲突</value>\n  </data>\n  <data name=\"Run_ConflictingKeywordInfo_Link.Content\" xml:space=\"preserve\">\n    <value>详细了解唤醒词冲突</value>\n  </data>\n  <data name=\"MeasureTool_ContinuousCapture_Information.Title\" xml:space=\"preserve\">\n    <value>实时测量会增加系统开销，并且不支持录屏和截屏</value>\n    <comment>pointer as in mouse pointer. Resources refer to things like CPU, GPU, RAM</comment>\n  </data>\n  <data name=\"QuickAccent_Description_Indicator.Header\" xml:space=\"preserve\">\n    <value>显示选中字符的 Unicode 编码和名称</value>\n  </data>\n  <data name=\"QuickAccent_SortByUsageFrequency_Indicator.Header\" xml:space=\"preserve\">\n    <value>按使用频率排序</value>\n  </data>\n  <data name=\"QuickAccent_SortByUsageFrequency_Indicator.Description\" xml:space=\"preserve\">\n    <value>根据每个字符的选中次数排序</value>\n  </data>\n  <data name=\"QuickAccent_StartSelectionFromTheLeft_Indicator.Header\" xml:space=\"preserve\">\n    <value>从左端开始选择</value>\n  </data>\n  <data name=\"QuickAccent_StartSelectionFromTheLeft_Indicator.Description\" xml:space=\"preserve\">\n    <value>使用方向键时原来是从中间开始选择，打开后是从左边第一项开始选择</value>\n  </data>\n  <data name=\"QuickAccent_DisableFullscreen.Header\" xml:space=\"preserve\">\n    <value>游戏模式中禁用</value>\n  </data>\n  <data name=\"QuickAccent_Language.Header\" xml:space=\"preserve\">\n    <value>语言</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage.Header\" xml:space=\"preserve\">\n    <value>指定语言</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage.Description\" xml:space=\"preserve\">\n    <value>显示所选语言的标记字母</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_All.Content\" xml:space=\"preserve\">\n    <value>全部</value>\n  </data>\n  <data name=\"QuickAccent_Group_Special\" xml:space=\"preserve\">\n    <value>符号</value>\n  </data>\n  <data name=\"QuickAccent_Group_Language\" xml:space=\"preserve\">\n    <value>语言</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Special\" xml:space=\"preserve\">\n    <value>特殊字符</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Bulgarian\" xml:space=\"preserve\">\n    <value>保加利亚语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Catalan\" xml:space=\"preserve\">\n    <value>加泰罗尼亚语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Crimean\" xml:space=\"preserve\">\n    <value>克里米亚鞑靼语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Currency\" xml:space=\"preserve\">\n    <value>货币符号</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Croatian\" xml:space=\"preserve\">\n    <value>克罗地亚语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Czech\" xml:space=\"preserve\">\n    <value>捷克语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Danish\" xml:space=\"preserve\">\n    <value>丹麦语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Gaeilge\" xml:space=\"preserve\">\n    <value>爱尔兰盖尔语</value>\n    <comment>Gaelic language spoken in Ireland</comment>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Gaidhlig\" xml:space=\"preserve\">\n    <value>苏格兰盖尔语</value>\n    <comment>Scottish Gaelic</comment>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_German\" xml:space=\"preserve\">\n    <value>德语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Greek\" xml:space=\"preserve\">\n    <value>希腊语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Hebrew\" xml:space=\"preserve\">\n    <value>希伯来语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_French\" xml:space=\"preserve\">\n    <value>法语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Finnish\" xml:space=\"preserve\">\n    <value>芬兰语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Estonian\" xml:space=\"preserve\">\n    <value>爱沙尼亚语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Esperanto\" xml:space=\"preserve\">\n    <value>世界语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_IPA\" xml:space=\"preserve\">\n    <value>国际音标</value>\n    <comment>International Phonetic Alphabet</comment>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Lithuanian\" xml:space=\"preserve\">\n    <value>立陶宛语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Macedonian\" xml:space=\"preserve\">\n    <value>马其顿语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Maori\" xml:space=\"preserve\">\n    <value>毛利语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Romanization\" xml:space=\"preserve\">\n    <value>中东语言罗马化</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Dutch\" xml:space=\"preserve\">\n    <value>荷兰语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Norwegian\" xml:space=\"preserve\">\n    <value>挪威语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Pinyin\" xml:space=\"preserve\">\n    <value>汉语拼音</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Proto_Indo_European\" xml:space=\"preserve\">\n    <value>原始印欧语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Polish\" xml:space=\"preserve\">\n    <value>波兰语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Portuguese\" xml:space=\"preserve\">\n    <value>葡萄牙语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Slovak\" xml:space=\"preserve\">\n    <value>斯洛伐克语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Slovenian\" xml:space=\"preserve\">\n    <value>斯洛文尼亚语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Spanish\" xml:space=\"preserve\">\n    <value>西班牙语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Swedish\" xml:space=\"preserve\">\n    <value>瑞典语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Turkish\" xml:space=\"preserve\">\n    <value>土耳其语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Icelandic\" xml:space=\"preserve\">\n    <value>冰岛语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Romanian\" xml:space=\"preserve\">\n    <value>罗马尼亚语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Serbian\" xml:space=\"preserve\">\n    <value>塞尔维亚语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Serbian_Cyrillic\" xml:space=\"preserve\">\n    <value>塞尔维亚语西里尔字母</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Hungarian\" xml:space=\"preserve\">\n    <value>匈牙利语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Italian\" xml:space=\"preserve\">\n    <value>意大利语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Kurdish\" xml:space=\"preserve\">\n    <value>库尔德语</value>\n  </data>\n  <data name=\"QuickAccent_SelectedLanguage_Welsh\" xml:space=\"preserve\">\n    <value>威尔士语</value>\n  </data>\n  <data name=\"Hosts.ModuleDescription\" xml:space=\"preserve\">\n    <value>轻松编辑 Hosts 域名表文件。</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"Hosts.ModuleTitle\" xml:space=\"preserve\">\n    <value>域名表</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"Shell_Hosts.Content\" xml:space=\"preserve\">\n    <value>域名表</value>\n    <comment>Products name: Navigation view item name for Hosts File Editor</comment>\n  </data>\n  <data name=\"Hosts_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用域名表工具</value>\n    <comment>\"Hosts File Editor\" is the name of the utility</comment>\n  </data>\n  <data name=\"Hosts_Toggle_ShowStartupWarning.Header\" xml:space=\"preserve\">\n    <value>显示启动警告</value>\n  </data>\n  <data name=\"Hosts_Activation_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"Hosts_LaunchButtonControl.Description\" xml:space=\"preserve\">\n    <value>管理域名解析列表</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"Hosts_LaunchButtonControl.Header\" xml:space=\"preserve\">\n    <value>启动域名表编辑器</value>\n    <comment>\"Hosts File Editor\" is a product name</comment>\n  </data>\n  <data name=\"Hosts_LaunchButton_Accessible.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>启动域名表编辑器</value>\n    <comment>\"Hosts File Editor\" is a product name</comment>\n  </data>\n  <data name=\"Hosts_AdditionalLinesPosition.Header\" xml:space=\"preserve\">\n    <value>注释段位置</value>\n  </data>\n  <data name=\"Hosts_AdditionalLinesPosition_Bottom.Content\" xml:space=\"preserve\">\n    <value>文件底端</value>\n  </data>\n  <data name=\"Hosts_AdditionalLinesPosition_Top.Content\" xml:space=\"preserve\">\n    <value>文件顶端</value>\n  </data>\n  <data name=\"Hosts_Behavior_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"Launch_Hosts.Content\" xml:space=\"preserve\">\n    <value>启动编辑器</value>\n    <comment>\"Hosts File Editor\" is the name of the utility</comment>\n  </data>\n  <data name=\"LearnMore_Hosts.Text\" xml:space=\"preserve\">\n    <value>详细了解域名表工具</value>\n    <comment>\"Hosts File Editor\" is the name of the utility</comment>\n  </data>\n  <data name=\"Oobe_Hosts.Description\" xml:space=\"preserve\">\n    <value>便捷的 Hosts 域名表文件（或称主机文件）编辑器，快速修改本机域名解析设置。</value>\n    <comment>\"Hosts File Editor\" is the name of the utility</comment>\n  </data>\n  <data name=\"Oobe_Hosts.Title\" xml:space=\"preserve\">\n    <value>域名表</value>\n    <comment>\"Hosts File Editor\" is the name of the utility</comment>\n  </data>\n  <data name=\"Hosts_Toggle_LaunchAdministrator.Description\" xml:space=\"preserve\">\n    <value>需要管理员权限才可以修改 Hosts 文件</value>\n  </data>\n  <data name=\"Hosts_Toggle_LaunchAdministrator.Header\" xml:space=\"preserve\">\n    <value>以管理员身份运行</value>\n  </data>\n  <data name=\"EnvironmentVariables.ModuleDescription\" xml:space=\"preserve\">\n    <value>管理系统的环境变量。</value>\n  </data>\n  <data name=\"EnvironmentVariables.ModuleTitle\" xml:space=\"preserve\">\n    <value>环境变量</value>\n  </data>\n  <data name=\"Shell_EnvironmentVariables.Content\" xml:space=\"preserve\">\n    <value>环境变量</value>\n  </data>\n  <data name=\"EnvironmentVariables_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用环境变量工具</value>\n  </data>\n  <data name=\"EnvironmentVariables_Activation_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"EnvironmentVariables_LaunchButtonControl.Description\" xml:space=\"preserve\">\n    <value>管理环境变量</value>\n  </data>\n  <data name=\"EnvironmentVariables_LaunchButtonControl.Header\" xml:space=\"preserve\">\n    <value>启动环境变量编辑器</value>\n  </data>\n  <data name=\"EnvironmentVariables_LaunchButton_Accessible.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>启动环境变量编辑器</value>\n  </data>\n  <data name=\"Launch_EnvironmentVariables.Content\" xml:space=\"preserve\">\n    <value>启动环境变量编辑器</value>\n  </data>\n  <data name=\"LearnMore_EnvironmentVariables.Text\" xml:space=\"preserve\">\n    <value>详细了解环境变量工具</value>\n  </data>\n  <data name=\"Oobe_EnvironmentVariables.Description\" xml:space=\"preserve\">\n    <value>便捷的环境变量管理工具，可以编辑变量，也可以套用模板方便管理。</value>\n  </data>\n  <data name=\"Oobe_EnvironmentVariables.Title\" xml:space=\"preserve\">\n    <value>环境变量</value>\n  </data>\n  <data name=\"EnvironmentVariables_Toggle_LaunchAdministrator.Description\" xml:space=\"preserve\">\n    <value>修改系统级环境变量需要管理员权限</value>\n  </data>\n  <data name=\"EnvironmentVariables_Toggle_LaunchAdministrator.Header\" xml:space=\"preserve\">\n    <value>以管理员身份启动</value>\n  </data>\n  <data name=\"ShortcutGuide_PressTimeForTaskbarIconShortcuts.Header\" xml:space=\"preserve\">\n    <value>显示任务栏指示标的长按时间（毫秒）</value>\n    <comment>ms = milliseconds</comment>\n  </data>\n  <data name=\"FileLocksmith.ModuleDescription\" xml:space=\"preserve\">\n    <value>查看、解除文件占用。</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"FileLocksmith.ModuleTitle\" xml:space=\"preserve\">\n    <value>文件开锁匠</value>\n  </data>\n  <data name=\"Shell_FileLocksmith.Content\" xml:space=\"preserve\">\n    <value>文件开锁匠</value>\n    <comment>Product name: Navigation view item name for FileLocksmith</comment>\n  </data>\n  <data name=\"FileLocksmith_Enable_FileLocksmith.Header\" xml:space=\"preserve\">\n    <value>启用文件开锁匠</value>\n    <comment>File Locksmith is the name of the utility</comment>\n  </data>\n  <data name=\"FileLocksmith_Toggle_StandardContextMenu.Content\" xml:space=\"preserve\">\n    <value>右键菜单和扩展右键菜单</value>\n  </data>\n  <data name=\"FileLocksmith_Toggle_ExtendedContextMenu.Content\" xml:space=\"preserve\">\n    <value>仅扩展右键菜单</value>\n  </data>\n  <data name=\"FileLocksmith_Toggle_ContextMenu.Header\" xml:space=\"preserve\">\n    <value>显示位置</value>\n  </data>\n  <data name=\"FileLocksmith_ShellIntegration.Header\" xml:space=\"preserve\">\n    <value>右键菜单集成</value>\n    <comment>This refers to directly integrating in with Windows</comment>\n  </data>\n  <data name=\"GPO_SettingIsManaged.Title\" xml:space=\"preserve\">\n    <value>组策略已控制此设置</value>\n  </data>\n  <data name=\"Hosts_AdditionalLinesPosition.Description\" xml:space=\"preserve\">\n    <value>包括注释和无法解析的内容</value>\n  </data>\n  <data name=\"TextExtractor_Languages.Header\" xml:space=\"preserve\">\n    <value>首选语言</value>\n  </data>\n  <data name=\"Alternate_OOBE_AlwaysOnTop_Description.Text\" xml:space=\"preserve\">\n    <value>一键置顶窗口</value>\n  </data>\n  <data name=\"Alternate_OOBE_AlwaysOnTop_Title.Text\" xml:space=\"preserve\">\n    <value>窗口置顶</value>\n    <comment>{Locked}</comment>\n  </data>\n  <data name=\"Alternate_OOBE_ColorPicker_Description.Text\" xml:space=\"preserve\">\n    <value>抓取屏幕颜色</value>\n  </data>\n  <data name=\"Alternate_OOBE_ColorPicker_Title.Text\" xml:space=\"preserve\">\n    <value>取色器</value>\n  </data>\n  <data name=\"Alternate_OOBE_Description.Text\" xml:space=\"preserve\">\n    <value>欢迎尝试以下功能</value>\n  </data>\n  <data name=\"Alternate_OOBE_FancyZones_Description.Text\" xml:space=\"preserve\">\n    <value>快速排列窗口</value>\n  </data>\n  <data name=\"Alternate_OOBE_FancyZones_Title.Text\" xml:space=\"preserve\">\n    <value>窗口布局</value>\n  </data>\n  <data name=\"Alternate_OOBE_Run_Description.Text\" xml:space=\"preserve\">\n    <value>搜索文件与信息</value>\n  </data>\n  <data name=\"Alternate_OOBE_Run_Title.Text\" xml:space=\"preserve\">\n    <value>快捷启动器</value>\n  </data>\n  <data name=\"General_Experimentation.Header\" xml:space=\"preserve\">\n    <value>功能测试</value>\n  </data>\n  <data name=\"GeneralPage_EnableExperimentation.Description\" xml:space=\"preserve\">\n    <value>汉化版移除了内测检测，打开即可享用新功能</value>\n    <comment>{Locked=\"Windows Insider\"}</comment>\n  </data>\n  <data name=\"GeneralPage_EnableExperimentation.Header\" xml:space=\"preserve\">\n    <value>开启新功能测试</value>\n  </data>\n  <data name=\"General_DiagnosticsAndFeedback.Header\" xml:space=\"preserve\">\n    <value>诊断数据</value>\n  </data>\n  <data name=\"GeneralPage_DiagnosticsAndFeedback_Link.Content\" xml:space=\"preserve\">\n    <value>详细了解我们收集的信息及其用途</value>\n  </data>\n  <data name=\"GeneralPage_EnableDataDiagnostics.Header\" xml:space=\"preserve\">\n    <value>发送诊断数据</value>\n  </data>\n  <data name=\"GeneralPage_EnableDataDiagnostics.Description\" xml:space=\"preserve\">\n    <value>帮助我们修复错误和优化性能</value>\n  </data>\n  <data name=\"GeneralPage_ViewDiagnosticData.Header\" xml:space=\"preserve\">\n    <value>查看诊断数据</value>\n  </data>\n  <data name=\"GeneralPage_EnableViewDiagnosticData.Header\" xml:space=\"preserve\">\n    <value>启用诊断数据查看器</value>\n  </data>\n  <data name=\"GeneralPage_EnableViewDiagnosticData.Description\" xml:space=\"preserve\">\n    <value>可能会占用大约 1GB 的空间</value>\n  </data>\n  <data name=\"GeneralPage_ViewDiagnosticDataViewer.Header\" xml:space=\"preserve\">\n    <value>查看诊断数据</value>\n  </data>\n  <data name=\"GeneralPage_ViewDiagnosticDataViewer.Description\" xml:space=\"preserve\">\n    <value>诊断数据查看器会创建可读的 XML 诊断数据，目录包含 .xml 和 .etl 文件</value>\n  </data>\n  <data name=\"Shell_AdvancedPaste.Content\" xml:space=\"preserve\">\n    <value>高级粘贴</value>\n    <comment>Product name: Navigation view item name for Advanced Paste</comment>\n  </data>\n  <data name=\"AdvancedPaste.ModuleDescription\" xml:space=\"preserve\">\n    <value>将复制的文本内容粘贴为纯文本、Markdown、JSON 等各种格式，也可以使用在线 AI 来为您执行自定义格式化。</value>\n  </data>\n  <data name=\"AdvancedPaste.ModuleTitle\" xml:space=\"preserve\">\n    <value>高级粘贴</value>\n  </data>\n  <data name=\"AdvancedPaste_Cancel\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用高级粘贴</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAISettingsGroup.Header\" xml:space=\"preserve\">\n    <value>AI 粘贴</value>\n  </data>\n  <data name=\"AdvancedPaste_BehaviorSettingsGroup.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"AdvancedPaste_ShowCustomPreviewSettingsCard.Header\" xml:space=\"preserve\">\n    <value>预览结果</value>\n  </data>\n  <data name=\"AdvancedPaste_ShowCustomPreviewSettingsCard.Description\" xml:space=\"preserve\">\n    <value>粘贴前检查 AI 输出的格式化结果</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAdvancedAI.Header\" xml:space=\"preserve\">\n    <value>启用高级 AI</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAdvancedAI.Description\" xml:space=\"preserve\">\n    <value>使用 Semantic Kernel 框架和更强大的模型，它拥有更强的文件图像处理能力，并且可以进行链式操作，但注意它会消耗更多 API 额度</value>\n  </data>\n  <data name=\"Oobe_AdvancedPaste.Description\" xml:space=\"preserve\">\n    <value>高级粘贴是一个为开发者准备的剪贴板工具，可以将复制的文本内容转换为任何需要的格式来粘贴。纯文本、Markdown、JSON 的格式化功能均在本地执行，AI 自定义格式化需要使用 OpenAI 的密钥来联网执行。注意，执行格式化后，剪贴板里原本的文本会被格式化后的文本覆盖。</value>\n  </data>\n  <data name=\"Oobe_AdvancedPaste.Title\" xml:space=\"preserve\">\n    <value>高级粘贴</value>\n  </data>\n  <data name=\"Oobe_AdvancedPasteUI_HowToUse.Text\" xml:space=\"preserve\">\n    <value>打开高级粘贴面板，选择要粘贴的格式。</value>\n  </data>\n  <data name=\"Oobe_AdvancedPastePlain_HowToUse.Text\" xml:space=\"preserve\">\n    <value>直接以纯文本粘贴。</value>\n  </data>\n  <data name=\"Oobe_AdvancedPasteMarkdown_HowToUse.Text\" xml:space=\"preserve\">\n    <value>直接转换为 Markdown 格式粘贴。原内容需要是 HTML 格式的。</value>\n  </data>\n  <data name=\"Oobe_AdvancedPasteJson_HowToUse.Text\" xml:space=\"preserve\">\n    <value>直接转换为 JSON 格式粘贴。原内容需要是 XML 或 CSV 格式。</value>\n  </data>\n  <data name=\"Oobe_AdvancedPasteCustom_HowToUse.Text\" xml:space=\"preserve\">\n    <value>打开 AI 格式化对话框，用 AI 将内容转换为所需格式。</value>\n  </data>\n  <data name=\"Shell_CmdNotFound.Content\" xml:space=\"preserve\">\n    <value>未找到命令</value>\n    <comment>Product name: Navigation view item name for Command Not Found</comment>\n  </data>\n  <data name=\"CmdNotFound.ModuleDescription\" xml:space=\"preserve\">\n    <value>在 PowerShedll 命令报错后自动检测并推荐可能需要安装的 WinGet 包。</value>\n    <comment>\"Command Not Found\" is a product name</comment>\n  </data>\n  <data name=\"CmdNotFound.ModuleTitle\" xml:space=\"preserve\">\n    <value>未找到命令</value>\n    <comment>\"Command Not Found\" is a product name</comment>\n  </data>\n  <data name=\"InstalledLabel.Text\" xml:space=\"preserve\">\n    <value>已安装</value>\n  </data>\n  <data name=\"DetectedLabel.Text\" xml:space=\"preserve\">\n    <value>存在</value>\n  </data>\n  <data name=\"NotDetectedLabel.Text\" xml:space=\"preserve\">\n    <value>不存在</value>\n  </data>\n  <data name=\"CmdNotFound_RequirementsBar.Title\" xml:space=\"preserve\">\n    <value>需要安装以下组件</value>\n  </data>\n  <data name=\"CmdNotFound_PowerShellDetection.Header\" xml:space=\"preserve\">\n    <value>PowerShell 7.4 或更高版本</value>\n  </data>\n  <data name=\"CmdNotFound_WinGetClientDetection.Header\" xml:space=\"preserve\">\n    <value>WinGet 客户端 PowerShell 模块</value>\n  </data>\n  <data name=\"CmdNotFound_Enable.Header\" xml:space=\"preserve\">\n    <value>未找到命令模块</value>\n    <comment>\"Command Not Found\" is a product name</comment>\n  </data>\n  <data name=\"CmdNotFound_Enable.Description\" xml:space=\"preserve\">\n    <value>将本模块添加到 PowerShell 7 配置文件脚本，以在新的会话中启用</value>\n  </data>\n  <data name=\"CmdNotFound_ModuleInstallationLogs.Text\" xml:space=\"preserve\">\n    <value>安装日志</value>\n  </data>\n  <data name=\"CmdNotFound_CheckPowerShellVersionButtonControl.Description\" xml:space=\"preserve\">\n    <value>使用本模块需要 PowerShell 7</value>\n  </data>\n  <data name=\"CmdNotFound_CheckCompatibility.Content\" xml:space=\"preserve\">\n    <value>刷新</value>\n  </data>\n  <data name=\"CmdNotFound_CheckCompatibilityTooltip.Text\" xml:space=\"preserve\">\n    <value>请检查您的 PowerShell 配置文件是否兼容且正确</value>\n  </data>\n  <data name=\"CmdNotFound_InstallButton.Content\" xml:space=\"preserve\">\n    <value>安装</value>\n  </data>\n  <data name=\"CmdNotFound_UninstallButton.Content\" xml:space=\"preserve\">\n    <value>卸载</value>\n  </data>\n  <data name=\"Oobe_CmdNotFound.Description\" xml:space=\"preserve\">\n    <value>未找到命令是一个 PowerShell 模块，检测命令报错，然后推荐可能需要的 WinGet 包。</value>\n    <comment>\"Command Not Found\" is a product name</comment>\n  </data>\n  <data name=\"Oobe_CmdNotFound.Title\" xml:space=\"preserve\">\n    <value>未找到命令</value>\n    <comment>\"Command Not Found\" is a product name</comment>\n  </data>\n  <data name=\"Oobe_CmdNotFound_HowToUse.Text\" xml:space=\"preserve\">\n    <value>当某个命令产生错误，本模块将附上可能包含所需可执行文件的 WinGet 包的安装命令。</value>\n  </data>\n  <data name=\"AllAppsTxt.Text\" xml:space=\"preserve\">\n    <value>所有工具</value>\n  </data>\n  <data name=\"BackBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>返回</value>\n  </data>\n  <data name=\"BackLabel.Text\" xml:space=\"preserve\">\n    <value>返回</value>\n  </data>\n  <data name=\"BugReportBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>反馈</value>\n  </data>\n  <data name=\"BugReportTooltip.Text\" xml:space=\"preserve\">\n    <value>反馈</value>\n  </data>\n  <data name=\"DocsBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>文档</value>\n  </data>\n  <data name=\"DocsTooltip.Text\" xml:space=\"preserve\">\n    <value>文档</value>\n  </data>\n  <data name=\"FZEditorString\" xml:space=\"preserve\">\n    <value>布局编辑器</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"MoreBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>更多</value>\n  </data>\n  <data name=\"MoreLabel.Text\" xml:space=\"preserve\">\n    <value>更多</value>\n  </data>\n  <data name=\"SettingsBtn.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"SettingsTooltip.Text\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"QuickAccessTxt.Text\" xml:space=\"preserve\">\n    <value>快捷面板</value>\n  </data>\n  <data name=\"UpdateAvailable.Title\" xml:space=\"preserve\">\n    <value>有可用更新</value>\n  </data>\n  <data name=\"FileExplorerPreview_Toggle_Monaco_Max_File_Size.Header\" xml:space=\"preserve\">\n    <value>允许文件大小</value>\n    <comment>Size refers to the disk space used by a file</comment>\n  </data>\n  <data name=\"FileExplorerPreview_Toggle_Monaco_Max_File_Size.Description\" xml:space=\"preserve\">\n    <value>限制预览文件的最大允许大小（KB），防止占用过多内存</value>\n    <comment>\"RAM\" refers to random access memory; \"size\" refers to disk space; \"bytes\" refer to the measurement unit</comment>\n  </data>\n  <data name=\"RegistryPreview.ModuleDescription\" xml:space=\"preserve\">\n    <value>可视化查看、编辑 .reg 注册表文件。</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"RegistryPreview.ModuleTitle\" xml:space=\"preserve\">\n    <value>注册表预览</value>\n  </data>\n  <data name=\"Shell_RegistryPreview.Content\" xml:space=\"preserve\">\n    <value>注册表预览</value>\n    <comment>Product name: Navigation view item name for Registry Preview</comment>\n  </data>\n  <data name=\"RegistryPreview_Enable_RegistryPreview.Header\" xml:space=\"preserve\">\n    <value>启用注册表预览工具</value>\n    <comment>Registry Preview is the name of the utility</comment>\n  </data>\n  <data name=\"Oobe_RegistryPreview_HowToUse.Text\" xml:space=\"preserve\">\n    <value>选中一个 .reg 注册表文件，单击 **右键**，选择 **预览**。</value>\n  </data>\n  <data name=\"Oobe_RegistryPreview_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>在文件管理器和 PowerToys 界面中都可以打开预览工具。</value>\n  </data>\n  <data name=\"Oobe_RegistryPreview.Description\" xml:space=\"preserve\">\n    <value>一个可视化的注册表文件编辑器。</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"Oobe_RegistryPreview.Title\" xml:space=\"preserve\">\n    <value>注册表预览</value>\n    <comment>Do not localize this string</comment>\n  </data>\n  <data name=\"LearnMore_RegistryPreview.Text\" xml:space=\"preserve\">\n    <value>详细了解注册表预览工具</value>\n    <comment>Registry Preview is a product name, do not loc</comment>\n  </data>\n  <data name=\"Launch_RegistryPreview.Content\" xml:space=\"preserve\">\n    <value>启动注册表预览工具</value>\n    <comment>\"Registry Preview\" is the name of the utility</comment>\n  </data>\n  <data name=\"MouseUtils_MouseJump.Header\" xml:space=\"preserve\">\n    <value>鼠标跳转</value>\n    <comment>Refers to the utility name</comment>\n  </data>\n  <data name=\"MouseUtils_MouseJump.Description\" xml:space=\"preserve\">\n    <value>在小地图中快速移动鼠标光标</value>\n    <comment>\"Mouse Jump\" is the name of the utility. Mouse is the hardware mouse.</comment>\n  </data>\n  <data name=\"MouseUtils_Enable_MouseJump.Header\" xml:space=\"preserve\">\n    <value>启用鼠标跳转</value>\n    <comment>\"Mouse Jump\" is the name of the utility.</comment>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ActivationShortcut.Description\" xml:space=\"preserve\">\n    <value>打开闪现小地图的快捷键</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ActivationShortcut.Header\" xml:space=\"preserve\">\n    <value>启动快捷键</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ThumbnailSize.Header\" xml:space=\"preserve\">\n    <value>小地图尺寸</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ThumbnailSize_Description_Prefix.Text\" xml:space=\"preserve\">\n    <value>限制小地图的图片尺寸为最大</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ThumbnailSize_Description_Suffix.Text\" xml:space=\"preserve\">\n    <value>像素</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ThumbnailSize_Edit_Height.Header\" xml:space=\"preserve\">\n    <value>最大高度（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ThumbnailSize_Edit_Width.Header\" xml:space=\"preserve\">\n    <value>最大宽度（像素）</value>\n    <comment>px = pixels</comment>\n  </data>\n  <data name=\"MouseUtils_MouseJump_Appearance.Header\" xml:space=\"preserve\">\n    <value>外观</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_PreviewType.Header\" xml:space=\"preserve\">\n    <value>小地图样式</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_PreviewType.Description\" xml:space=\"preserve\">\n    <value>选择一个模板或者自定义</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_PreviewType_Compact.Text\" xml:space=\"preserve\">\n    <value>简洁</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_PreviewType_Bezelled.Text\" xml:space=\"preserve\">\n    <value>边框</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_PreviewType_Custom.Text\" xml:space=\"preserve\">\n    <value>自定义</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_CopyStyle.Content\" xml:space=\"preserve\">\n    <value>用当前模板进行自定义</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BackgroundColor1.Header\" xml:space=\"preserve\">\n    <value>背景色 1</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BackgroundColor1.Description\" xml:space=\"preserve\">\n    <value>小地图背景的渐变开始色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BackgroundColor2.Header\" xml:space=\"preserve\">\n    <value>背景色 2</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BackgroundColor2.Description\" xml:space=\"preserve\">\n    <value>小地图背景的渐变结束色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BorderThickness.Header\" xml:space=\"preserve\">\n    <value>外边框厚度（像素）</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BorderThickness.Description\" xml:space=\"preserve\">\n    <value>整个小地图的边框的厚度</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BorderColor.Header\" xml:space=\"preserve\">\n    <value>外边框颜色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BorderColor.Description\" xml:space=\"preserve\">\n    <value>小地图边框的颜色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_Border3dDepth.Header\" xml:space=\"preserve\">\n    <value>外边框 3D 深度（像素）</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_Border3dDepth.Description\" xml:space=\"preserve\">\n    <value>小地图边框的 3D 效果的宽度</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BorderPadding.Header\" xml:space=\"preserve\">\n    <value>外边框间距（像素）</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BorderPadding.Description\" xml:space=\"preserve\">\n    <value>小地图边框与内容之间的间距</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BezelThickness.Header\" xml:space=\"preserve\">\n    <value>内边框厚度（像素）</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BezelThickness.Description\" xml:space=\"preserve\">\n    <value>每个屏幕的边框的厚度</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BezelColor.Header\" xml:space=\"preserve\">\n    <value>内边框颜色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_BezelColor.Description\" xml:space=\"preserve\">\n    <value>屏幕边框的颜色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_Bezel3dDepth.Header\" xml:space=\"preserve\">\n    <value>内边框 3D 深度（像素）</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_Bezel3dDepth.Description\" xml:space=\"preserve\">\n    <value>屏幕边框的 3D 效果的宽度</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ScreenMargin.Header\" xml:space=\"preserve\">\n    <value>屏幕间距（像素）</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ScreenMargin.Description\" xml:space=\"preserve\">\n    <value>各个屏幕之间的间距</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ScreenColor1.Header\" xml:space=\"preserve\">\n    <value>屏幕颜色 1</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ScreenColor1.Description\" xml:space=\"preserve\">\n    <value>屏幕背景的渐变开始色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ScreenColor2.Header\" xml:space=\"preserve\">\n    <value>屏幕颜色 2</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_ScreenColor2.Description\" xml:space=\"preserve\">\n    <value>屏幕背景的渐变结束色</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_CopyToCustomStyle_MessageBox_Title\" xml:space=\"preserve\">\n    <value>用当前模板进行自定义</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_CopyToCustomStyle_MessageBox_Text\" xml:space=\"preserve\">\n    <value>原本的自定义样式将被覆盖。</value>\n  </data>\n  <data name=\"MouseUtils_MouseJump_CopyToCustomStyle_MessageBox_PrimaryButtonText\" xml:space=\"preserve\">\n    <value>确定</value>\n  </data>\n  <data name=\"Hosts_Toggle_LoopbackDuplicates.Description\" xml:space=\"preserve\">\n    <value>127.0.0.1、::1 等</value>\n    <comment>\"127.0.0.1 and ::1\" are well known loopback addresses, do not loc</comment>\n  </data>\n  <data name=\"Hosts_Toggle_LoopbackDuplicates.Header\" xml:space=\"preserve\">\n    <value>将本地回环地址视作重复</value>\n  </data>\n  <data name=\"RegistryPreview_Launch_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"RegistryPreview_LaunchButton_Accessible.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>启动注册表预览工具</value>\n  </data>\n  <data name=\"RegistryPreview_LaunchButtonControl.Header\" xml:space=\"preserve\">\n    <value>启动注册表预览工具</value>\n  </data>\n  <data name=\"RegistryPreview_DefaultRegApp.Header\" xml:space=\"preserve\">\n    <value>作为默认打开方式</value>\n  </data>\n  <data name=\"RegistryPreview_DefaultRegApp.Description\" xml:space=\"preserve\">\n    <value>双击打开 .reg 注册表文件时，使用注册表预览工具来打开</value>\n    <comment>Registry Preview is app name. Do not localize.</comment>\n  </data>\n  <data name=\"AdvancedPaste_ShortcutWarning.Title\" xml:space=\"preserve\">\n    <value>覆盖 Ctrl+V 快捷键可能会导致图片、文件等无法粘贴，以及有些软件的格式化粘贴功能失效</value>\n  </data>\n  <data name=\"Oobe_Peek.Description\" xml:space=\"preserve\">\n    <value>给 Windows 系统也带来了雷雳般迅速的文件快速查看功能。</value>\n    <comment>{Locked=\"Windows\"}</comment>\n  </data>\n  <data name=\"Oobe_Peek.Title\" xml:space=\"preserve\">\n    <value>快速查看</value>\n  </data>\n  <data name=\"Oobe_Peek_HowToUse.Text\" xml:space=\"preserve\">\n    <value>预览选中的文件。</value>\n  </data>\n  <data name=\"MWB_PCNameLabel.PlaceholderText\" xml:space=\"preserve\">\n    <value>设备名称</value>\n  </data>\n  <data name=\"MWB_SecurityKeyLabel.PlaceholderText\" xml:space=\"preserve\">\n    <value>连接密码</value>\n  </data>\n  <data name=\"Hosts_Encoding.Description\" xml:space=\"preserve\">\n    <value>保存 Hosts 文件的编码</value>\n    <comment>\"Hosts\" refers to the system hosts file, do not loc</comment>\n  </data>\n  <data name=\"Hosts_Encoding.Header\" xml:space=\"preserve\">\n    <value>文件编码</value>\n  </data>\n  <data name=\"Hosts_Encoding_Utf8.Content\" xml:space=\"preserve\">\n    <value>UTF-8</value>\n  </data>\n  <data name=\"Hosts_Encoding_Utf8Bom.Content\" xml:space=\"preserve\">\n    <value>UTF-8 包含 BOM 标记</value>\n  </data>\n  <data name=\"MouseUtils_MouseHighlighter_AlwaysColor.Header\" xml:space=\"preserve\">\n    <value>松手颜色</value>\n  </data>\n  <data name=\"MouseUtils_MousePointerCrosshairs_CrosshairsAutoHide.Content\" xml:space=\"preserve\">\n    <value>隐藏鼠标指针时自动关闭准心</value>\n  </data>\n  <data name=\"MouseUtils_AutoActivate.Content\" xml:space=\"preserve\">\n    <value>启动后自动打开</value>\n  </data>\n  <data name=\"Run_FindMorePlugins.Text\" xml:space=\"preserve\">\n    <value>获取更多插件</value>\n  </data>\n  <data name=\"Run_PluginUseFindMorePlugins.Content\" xml:space=\"preserve\">\n    <value>获取更多插件</value>\n  </data>\n  <data name=\"GPO_SomeRunPluginsAreManaged.Title\" xml:space=\"preserve\">\n    <value>组策略已控制插件启用状态</value>\n  </data>\n  <data name=\"AlwaysOnTop_FrameOpacity.Header\" xml:space=\"preserve\">\n    <value>不透明度（%）</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ActivationCustomizedShortcut.Content\" xml:space=\"preserve\">\n    <value>自定义快捷键</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ActivationDoubleRightControlPress.Content\" xml:space=\"preserve\">\n    <value>双击右 Ctrl 键</value>\n    <comment>Right control is the physical key on the keyboard.</comment>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ActivationShortcut.Description\" xml:space=\"preserve\">\n    <value>按一下打开，再按一下关掉</value>\n  </data>\n  <data name=\"MouseUtils_FindMyMouse_ActivationShortcut.Header\" xml:space=\"preserve\">\n    <value>激活快捷键</value>\n  </data>\n  <data name=\"SettingsWindow_AdminTitle\" xml:space=\"preserve\">\n    <value>管理员权限: PowerToys 设置</value>\n    <comment>Title of the settings window when running as administrator</comment>\n  </data>\n  <data name=\"DashboardTitle.Text\" xml:space=\"preserve\">\n    <value>主页</value>\n  </data>\n  <data name=\"Shell_Dashboard.Content\" xml:space=\"preserve\">\n    <value>主页</value>\n  </data>\n  <data name=\"DisabledModules.Text\" xml:space=\"preserve\">\n    <value>禁用的模块</value>\n  </data>\n  <data name=\"EnabledModules.Text\" xml:space=\"preserve\">\n    <value>启用的模块</value>\n  </data>\n  <data name=\"Peek_Preview_GroupSettings.Header\" xml:space=\"preserve\">\n    <value>预览</value>\n  </data>\n  <data name=\"Peek_SourceCode_Header.Description\" xml:space=\"preserve\">\n    <value>.txt .cpp .py .json .xml .csproj 等，由 Monaco 提供支持</value>\n  </data>\n  <data name=\"Peek_SourceCode_Header.Header\" xml:space=\"preserve\">\n    <value>程序代码</value>\n  </data>\n  <data name=\"Peek_SourceCode_TryFormat.Description\" xml:space=\"preserve\">\n    <value>针对 json 和 xml，不会修改原文件</value>\n  </data>\n  <data name=\"Peek_SourceCode_TryFormat.Header\" xml:space=\"preserve\">\n    <value>自动格式化代码</value>\n  </data>\n  <data name=\"Peek_SourceCode_WrapText.Content\" xml:space=\"preserve\">\n    <value>自动换行</value>\n  </data>\n  <data name=\"Peek_SourceCode_Minimap.Content\" xml:space=\"preserve\">\n    <value>显示小地图</value>\n  </data>\n  <data name=\"ShowPluginsOverview_All.Content\" xml:space=\"preserve\">\n    <value>所有唤醒词</value>\n  </data>\n  <data name=\"ShowPluginsOverview_None.Content\" xml:space=\"preserve\">\n    <value>关闭</value>\n  </data>\n  <data name=\"ShowPluginsOverview_NonGlobal.Content\" xml:space=\"preserve\">\n    <value>不包含默认唤醒的</value>\n  </data>\n  <data name=\"PowerLauncher_TitleFontSize.Description\" xml:space=\"preserve\">\n    <value>输入框和搜索结果标题的字号</value>\n  </data>\n  <data name=\"PowerLauncher_TitleFontSize.Header\" xml:space=\"preserve\">\n    <value>字体大小（点）</value>\n  </data>\n  <data name=\"PowerLauncher_TextFontSizeSlider.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>搜索结果字号</value>\n  </data>\n  <data name=\"GeneralPage_ShowWhatsNewAfterUpdates.Content\" xml:space=\"preserve\">\n    <value>更新完成后打开更新日志</value>\n  </data>\n  <data name=\"QuickAccent_Prevent_Activation_On_Game_Mode.Content\" xml:space=\"preserve\">\n    <value>游戏模式中禁用</value>\n    <comment>\"Game mode\" is the Windows feature to prevent notification when playing a game.</comment>\n  </data>\n  <data name=\"GeneralPage_ShowNewUpdatesToast.Header\" xml:space=\"preserve\">\n    <value>显示版本更新通知</value>\n  </data>\n  <data name=\"GPO_SomeSettingsAreManaged.Title\" xml:space=\"preserve\">\n    <value>组策略已控制这些设置</value>\n  </data>\n  <data name=\"GPO_AdvancedPasteAi_SettingIsManaged.Title\" xml:space=\"preserve\">\n    <value>组策略已控制 AI 功能</value>\n  </data>\n  <data name=\"GPO_SettingIsManaged_ToolTip.Text\" xml:space=\"preserve\">\n    <value>组策略已控制此设置</value>\n  </data>\n  <data name=\"GPO_SomePreviewPanesAreManaged.Title\" xml:space=\"preserve\">\n    <value>组策略已控制预览窗格增强模块启用状态</value>\n  </data>\n  <data name=\"GPO_SomeThumbnailProvidersAreManaged.Title\" xml:space=\"preserve\">\n    <value>组策略已控制缩略图增强模块启用状态</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Monaco_Sticky_Scroll.Content\" xml:space=\"preserve\">\n    <value>启用粘滞滚动</value>\n  </data>\n  <data name=\"Peek_SourceCode_StickyScroll.Content\" xml:space=\"preserve\">\n    <value>启用粘滞滚动</value>\n  </data>\n  <data name=\"FileExplorerPreview_ToggleSwitch_Monaco_Minimap.Content\" xml:space=\"preserve\">\n    <value>显示小地图</value>\n  </data>\n  <data name=\"PrivacyLink.Text\" xml:space=\"preserve\">\n    <value>OpenAI 隐私政策</value>\n  </data>\n  <data name=\"TermsLink.Text\" xml:space=\"preserve\">\n    <value>OpenAI 使用条款</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialog_Description.Text\" xml:space=\"preserve\">\n    <value>利用 AI 的力量，您可以将复制的文本转换为任何需要的格式。点击了解 OpenAI 的相关条款：</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialog_LoginIntoText.Text\" xml:space=\"preserve\">\n    <value>• 登录您的</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialog_ConfigureOpenAIKey.Text\" xml:space=\"preserve\">\n    <value>配置 OpenAI 密钥</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialog_OpenAIApiKeysOverviewText.Text\" xml:space=\"preserve\">\n    <value>OpenAI API 密钥管理页面</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialog_CreateNewKeyText.Text\" xml:space=\"preserve\">\n    <value>• 新建一个密钥，粘贴到这里</value>\n  </data>\n  <data name=\"FileExplorerPreview_Toggle_Monaco_Font_Size.Description\" xml:space=\"preserve\">\n    <value>编辑器字体大小，推荐 14 点</value>\n    <comment>{Locked=\"pt\"}</comment>\n  </data>\n  <data name=\"FileExplorerPreview_Toggle_Monaco_Font_Size.Header\" xml:space=\"preserve\">\n    <value>字号</value>\n  </data>\n  <data name=\"Peek_SourceCode_FontSize.Description\" xml:space=\"preserve\">\n    <value>编辑器字体大小，推荐 14 点</value>\n    <comment>{Locked=\"pt\"}</comment>\n  </data>\n  <data name=\"Peek_SourceCode_FontSize.Header\" xml:space=\"preserve\">\n    <value>字号</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialog_NoteAICreditsText.Text\" xml:space=\"preserve\">\n    <value>• 注意：要使用该功能，您需要在 OpenAI 账户中有可用 API 额度。如果额度用尽，您将收到 “API 密钥额度已用尽” 错误</value>\n  </data>\n  <data name=\"AdvancedPaste_EnableAIDialog_NoteAICreditsErrorText.Text\" xml:space=\"preserve\">\n    <value>如果额度用尽，您将收到 “API 密钥额度已用尽” 错误</value>\n  </data>\n  <data name=\"AdvancedPaste_CloseAfterLosingFocus.Header\" xml:space=\"preserve\">\n    <value>失去焦点自动关闭（点击粘贴面板之外就会关闭）</value>\n    <comment>AdvancedPaste is a product name, do not loc</comment>\n  </data>\n  <data name=\"GPO_CommandNotFound_ForceDisabled.Title\" xml:space=\"preserve\">\n    <value>组策略已禁用未找到命令模块</value>\n    <comment>\"Command Not Found\" is a product name</comment>\n  </data>\n  <data name=\"GPO_CommandNotFound_ForceEnabled.Title\" xml:space=\"preserve\">\n    <value>组策略已启用未找到命令模块</value>\n    <comment>\"Command Not Found\" is a product name</comment>\n  </data>\n  <data name=\"NewPlus.ModuleTitle\" xml:space=\"preserve\">\n    <value>新建+</value>\n    <comment>New+ is the name of the utility. Localize product name in accordance with Windows New</comment>\n  </data>\n  <data name=\"NewPlus.ModuleDescription\" xml:space=\"preserve\">\n    <value>从自定义模板新建文件与文件夹。</value>\n  </data>\n  <data name=\"NewPlus_Product_Name.Content\" xml:space=\"preserve\">\n    <value>新建+</value>\n    <comment>New+ is the name of the utility. Localize product name in accordance with Windows New</comment>\n  </data>\n  <data name=\"NewPlus_Product_Description.Description\" xml:space=\"preserve\">\n    <value>从模板新建文件与文件夹</value>\n    <comment>New+ product description</comment>\n  </data>\n  <data name=\"NewPlus_Learn_More.Text\" xml:space=\"preserve\">\n    <value>详细了解新建+</value>\n    <comment>New+ learn more link. Localize product name in accordance with Windows New</comment>\n  </data>\n  <data name=\"NewPlus_Enable_Toggle.Header\" xml:space=\"preserve\">\n    <value>启用新建+</value>\n    <comment>Localize product name in accordance with Windows New</comment>\n  </data>\n  <data name=\"NewPlus_TemplatesNotBackupAndRestoreWarning.Title\" xml:space=\"preserve\">\n    <value>目前 PowerToys 备份功能暂不支持新建+的模板，如需备份请手动复制模板</value>\n  </data>\n  <data name=\"NewPlus_Templates.Header\" xml:space=\"preserve\">\n    <value>模板</value>\n    <comment>Templates label</comment>\n  </data>\n  <data name=\"NewPlus_Templates_Location.Header\" xml:space=\"preserve\">\n    <value>模板文件夹位置</value>\n    <comment>Templates Location label</comment>\n  </data>\n  <data name=\"NewPlus_Templates_Location_Path.Text\" xml:space=\"preserve\">\n    <value>...</value>\n    <comment>Do not localize</comment>\n  </data>\n  <data name=\"NewPlus_Templates_Location_Learn_More.Content\" xml:space=\"preserve\">\n    <value>了解模板文件夹的高级用法</value>\n    <comment>Read more about templates location</comment>\n  </data>\n  <data name=\"NewPlus_Templates_Location_Change.Content\" xml:space=\"preserve\">\n    <value>更改</value>\n    <comment>Button where user can Change the location of New templates</comment>\n  </data>\n  <data name=\"NewPlus_Display_Options.Header\" xml:space=\"preserve\">\n    <value>显示</value>\n    <comment>Display options label</comment>\n  </data>\n  <data name=\"NewPlus_Hide_File_Extension_Toggle.Header\" xml:space=\"preserve\">\n    <value>隐藏模板文件扩展名</value>\n    <comment>Template file name extension settings toggle</comment>\n  </data>\n  <data name=\"NewPlus_Hide_Starting_Digits_Toggle.Header\" xml:space=\"preserve\">\n    <value>隐藏模板文件名开头的数字、空格、点</value>\n    <comment>Template filename starting digits settings toggle</comment>\n  </data>\n  <data name=\"NewPlus_Hide_Starting_Digits_Description.Text\" xml:space=\"preserve\">\n    <value>可以在文件名开头添加 1. 2. 这样的序号来控制模板的排列顺序</value>\n    <comment>Template filename starting digits settings toggle</comment>\n  </data>\n  <data name=\"NewPlus.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit</comment>\n  </data>\n  <data name=\"Oobe_NewPlus.Title\" xml:space=\"preserve\">\n    <value>新建+</value>\n    <comment>New+ is the name of the utility. Localize product name in accordance with Windows New</comment>\n  </data>\n  <data name=\"Oobe_NewPlus.Description\" xml:space=\"preserve\">\n    <value>从自定义模板新建文件与文件夹。</value>\n  </data>\n  <data name=\"Oobe_NewPlus_HowToUse.Text\" xml:space=\"preserve\">\n    <value>在文件夹中单击右键，在右键菜单中选择 \"新建+\"，然后就能选择要放置哪个新建模板了。选择 \"打开模板文件夹\" 可以添加新的模板。</value>\n  </data>\n  <data name=\"Oobe_NewPlus_TipsAndTricks.Text\" xml:space=\"preserve\">\n    <value>您可以为各种用途添加不同的模板，例如记录日常开支的 Excel 表格模板、制作宣传海报的 PSD 模板，甚至是一整个模板代码项目文件夹！只需放在模板文件夹内即可。</value>\n  </data>\n  <data name=\"Workspaces.ModuleDescription\" xml:space=\"preserve\">\n    <value>保存一组窗口布置，一键恢复工作状态。</value>\n  </data>\n  <data name=\"Workspaces.ModuleTitle\" xml:space=\"preserve\">\n    <value>工作区</value>\n  </data>\n  <data name=\"Workspaces_ShortDescription\" xml:space=\"preserve\">\n    <value>创建与启动工作区</value>\n  </data>\n  <data name=\"Shell_ZoomIt.Content\" xml:space=\"preserve\">\n    <value>演示工具</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"ZoomIt_EnableToggleControl_HeaderText.Header\" xml:space=\"preserve\">\n    <value>启用演示工具</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"ZoomIt.ModuleDescription\" xml:space=\"preserve\">\n    <value>在汇报和现场演示时，帮助你放大屏幕、批注打字、截图录屏。</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"ZoomIt_ShortDescription\" xml:space=\"preserve\">\n    <value>可以放大、批注、截图录屏的演示工具。</value>\n  </data>\n  <data name=\"ZoomIt.ModuleTitle\" xml:space=\"preserve\">\n    <value>演示工具</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"LearnMore_ZoomIt.Text\" xml:space=\"preserve\">\n    <value>详细了解演示工具</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"ZoomIt.SecondaryLinksHeader\" xml:space=\"preserve\">\n    <value>贡献</value>\n    <comment>giving credit to the projects this utility was based on</comment>\n  </data>\n  <data name=\"ZoomIt_SimultaneousStandaloneZoomItWarning.Title\" xml:space=\"preserve\">\n    <value>原版 ZoomIt 软件不能和 PowerToys 版本同时使用，在开启前记得把原版软件退出哦</value>\n  </data>\n  <data name=\"ZoomIt_BehaviorGroup.Header\" xml:space=\"preserve\">\n    <value>功能</value>\n  </data>\n  <data name=\"ZoomIt_Toggle_ShowTrayIcon.Header\" xml:space=\"preserve\">\n    <value>显示托盘图标</value>\n  </data>\n  <data name=\"ZoomIt_ZoomGroup.Header\" xml:space=\"preserve\">\n    <value>放大</value>\n  </data>\n  <data name=\"ZoomIt_ZoomGroup.Description\" xml:space=\"preserve\">\n    <value>按下快捷键放大之后，滚动鼠标滚轮或按上下方向键可以缩放大小。\n按鼠标左键开始画图，按 Esc 键或鼠标右键退出放大。\n按 Ctrl+C 复制截图，Ctrl+Shift+C 框选并复制。\n按 Ctrl+S 保存截图，Ctrl+Shift+S 框选并保存。</value>\n  </data>\n  <data name=\"ZoomIt_Zoom_Shortcut.Header\" xml:space=\"preserve\">\n    <value>放大快捷键</value>\n  </data>\n  <data name=\"ZoomIt_Toggle_AnimateZoom.Header\" xml:space=\"preserve\">\n    <value>放大缩小动画</value>\n  </data>\n  <data name=\"ZoomIt_Slider_InitialMagnification.Header\" xml:space=\"preserve\">\n    <value>默认放大倍率</value>\n  </data>\n  <data name=\"ZoomIt_LiveZoomGroup.Header\" xml:space=\"preserve\">\n    <value>实时放大</value>\n  </data>\n  <data name=\"ZoomIt_LiveZoomGroup.Description\" xml:space=\"preserve\">\n    <value>这个模式下窗口能动。\n按 Ctrl+上下方向键 来缩放大小。\n按 画图快捷键 冻结画面开始画图，画完按 Esc 回到实时缩放中。\n按 Shift+实时放大快捷键 开始实时画图，画面不会冻结，按 Esc 返回。</value>\n  </data>\n  <data name=\"ZoomIt_LiveZoom_Shortcut.Header\" xml:space=\"preserve\">\n    <value>实时放大快捷键</value>\n  </data>\n  <data name=\"ZoomIt_DrawGroup.Header\" xml:space=\"preserve\">\n    <value>画图</value>\n  </data>\n  <data name=\"ZoomIt_DrawGroup.Description\" xml:space=\"preserve\">\n    <value>放大之后，点击左键开始画图，点击右键退出画图。按 Ctrl+Z 撤回，按 E 清空，按空格键将光标移到屏幕中央。\n\n粗细 - 按 Ctrl+鼠标滚轮或上下方向键 调整画笔粗细。\n颜色 - 按 R 红色、G 绿色、B 蓝色、O 橙色、Y 黄色、P 粉色。\n效果 - 按 Shift+颜色键 变成对应的半透明高光颜色。按 X 模糊，Shift+X 是更强力的模糊。\n形状 - 按住 Shift 画直线，按住 Ctrl 画矩形，按住 Tab 画椭圆，按住 Ctrl+Shift 画箭头。\n画板 - 按 W 清空全屏变成白色，K 变黑色。\n\n同样支持 Ctrl+C 复制和 Ctrl+S 保存等。</value>\n  </data>\n  <data name=\"ZoomIt_Draw_Shortcut.Header\" xml:space=\"preserve\">\n    <value>画图快捷键</value>\n  </data>\n  <data name=\"ZoomIt_TypeGroup.Header\" xml:space=\"preserve\">\n    <value>文本</value>\n  </data>\n  <data name=\"ZoomIt_TypeGroup.Description\" xml:space=\"preserve\">\n    <value>在画图时，按 T 输入文本，Shift+T 输入右对齐的文本。按 Esc 或单击左键结束文本输入。\n用鼠标滚轮或上下方向键改变字体大小。文本颜色就是当前的画笔颜色。</value>\n  </data>\n  <data name=\"ZoomIt_Type_TextFont.Header\" xml:space=\"preserve\">\n    <value>字体</value>\n  </data>\n  <data name=\"ZoomIt_Type_Font_Button.Content\" xml:space=\"preserve\">\n    <value>选择字体</value>\n    <comment>Font refers to text font</comment>\n  </data>\n  <data name=\"ZoomIt_DemoTypeGroup.Header\" xml:space=\"preserve\">\n    <value>自动打字</value>\n  </data>\n  <data name=\"ZoomIt_DemoTypeGroup.Description\" xml:space=\"preserve\">\n    <value>选择一个文件作为输入文本，按快捷键后自动一个个字地打出来。\n也可以从剪贴板里输入文本，剪贴板文本需要以 [start] 开头。\n\n用 [end] 可以分段，每次只打一段，用 [pause:n] 可以等待 n 秒。\n用 [paste] 和 [/paste] 括起来的部分可以一次性粘贴出来，不会一个个字地打。\n用 [enter]、[up]、[down]、[left]、[right] 表示回车和上下左右按键。\n\n默认是自动输出，如果开启半自动模式，那就是手动按一下键盘它打一两个字。\n在自动打字的过程中，键盘将会被它控制。半自动模式下，打完一段之后需要按空格键来结束控制。全自动模式下会自动结束控制。\n\n整个文件打完之后，将会重新加载文件并回到开头继续。按 Shift+自动打字快捷键 可以往回倒带一段。</value>\n  </data>\n  <data name=\"ZoomIt_DemoType_Shortcut.Header\" xml:space=\"preserve\">\n    <value>自动打字快捷键</value>\n  </data>\n  <data name=\"ZoomIt_DemoType_File.Header\" xml:space=\"preserve\">\n    <value>输入文本</value>\n  </data>\n  <data name=\"ZoomIt_DemoType_File_BrowseButton.Content\" xml:space=\"preserve\">\n    <value>选择文件</value>\n  </data>\n  <data name=\"ZoomIt_DemoType_File_Picker_Dialog_Title\" xml:space=\"preserve\">\n    <value>选择自动打字文件...</value>\n  </data>\n  <data name=\"FilePicker_AllFilesFilter\" xml:space=\"preserve\">\n    <value>全部文件</value>\n  </data>\n  <data name=\"ZoomIt_DemoType_Toggle_UserDrivenMode.Header\" xml:space=\"preserve\">\n    <value>半自动模式</value>\n  </data>\n  <data name=\"ZoomIt_DemoType_SpeedSlider.Header\" xml:space=\"preserve\">\n    <value>打字速度</value>\n  </data>\n  <data name=\"ZoomIt_DemoType_SpeedSlider_Thumbnail_Explanation\" xml:space=\"preserve\">\n    <value>越大越快</value>\n  </data>\n  <data name=\"ZoomIt_BreakGroup.Header\" xml:space=\"preserve\">\n    <value>倒计时</value>\n  </data>\n  <data name=\"ZoomIt_BreakGroup.Description\" xml:space=\"preserve\">\n    <value>按快捷键或使用托盘菜单来开始倒计时。按方向键增减时间，按 Esc 退出。\n\n如果中途使用 Alt+Tab 切换到了其他窗口，单击托盘图标可以返回计时窗口。\n计时器颜色可以按画笔颜色键切换，字体是画图文本字体。</value>\n  </data>\n  <data name=\"ZoomIt_Break_Shortcut.Header\" xml:space=\"preserve\">\n    <value>倒计时快捷键</value>\n  </data>\n  <data name=\"ZoomIt_Break_Timeout.Header\" xml:space=\"preserve\">\n    <value>默认分钟数</value>\n  </data>\n  <data name=\"ZoomIt_Break_ShowExpiredTime.Header\" xml:space=\"preserve\">\n    <value>计时结束继续显示超出的时间</value>\n  </data>\n  <data name=\"ZoomIt_Break_PlaySoundsFile.Header\" xml:space=\"preserve\">\n    <value>计时结束播放声音</value>\n  </data>\n  <data name=\"ZoomIt_Break_SoundFile.Header\" xml:space=\"preserve\">\n    <value>声音文件</value>\n  </data>\n  <data name=\"ZoomIt_Break_SoundFile_BrowseButton.Content\" xml:space=\"preserve\">\n    <value>选择</value>\n  </data>\n  <data name=\"ZoomIt_Break_SoundFile_Picker_Dialog_Title\" xml:space=\"preserve\">\n    <value>选择音频文件...</value>\n  </data>\n  <data name=\"FilePicker_ZoomIt_SoundsFilter\" xml:space=\"preserve\">\n    <value>音频文件</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity.Header\" xml:space=\"preserve\">\n    <value>窗口不透明度</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_10Percent.Content\" xml:space=\"preserve\">\n    <value>10%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_20Percent.Content\" xml:space=\"preserve\">\n    <value>20%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_30Percent.Content\" xml:space=\"preserve\">\n    <value>30%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_40Percent.Content\" xml:space=\"preserve\">\n    <value>40%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_50Percent.Content\" xml:space=\"preserve\">\n    <value>50%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_60Percent.Content\" xml:space=\"preserve\">\n    <value>60%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_70Percent.Content\" xml:space=\"preserve\">\n    <value>70%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_80Percent.Content\" xml:space=\"preserve\">\n    <value>80%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_90Percent.Content\" xml:space=\"preserve\">\n    <value>90%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerOpacity_100Percent.Content\" xml:space=\"preserve\">\n    <value>100%</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition.Header\" xml:space=\"preserve\">\n    <value>时间显示位置</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_TopLeftCorner.Content\" xml:space=\"preserve\">\n    <value>左上角</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_TopCenter.Content\" xml:space=\"preserve\">\n    <value>正上方</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_TopRightCorner.Content\" xml:space=\"preserve\">\n    <value>右上角</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_Left.Content\" xml:space=\"preserve\">\n    <value>左侧</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_Center.Content\" xml:space=\"preserve\">\n    <value>正中央</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_Right.Content\" xml:space=\"preserve\">\n    <value>右侧</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_BottomLeftCorner.Content\" xml:space=\"preserve\">\n    <value>左下角</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_BottomCenter.Content\" xml:space=\"preserve\">\n    <value>正下方</value>\n  </data>\n  <data name=\"ZoomIt_Break_TimerPosition_BottomRightCorner.Content\" xml:space=\"preserve\">\n    <value>右下角</value>\n  </data>\n  <data name=\"ZoomIt_Break_ShowBackgroundBitmap.Header\" xml:space=\"preserve\">\n    <value>背景图片</value>\n  </data>\n  <data name=\"ZoomIt_Break_ShowFadedDesktop.Content\" xml:space=\"preserve\">\n    <value>使用变暗的屏幕截图</value>\n  </data>\n  <data name=\"ZoomIt_Break_ShowImageFile.Content\" xml:space=\"preserve\">\n    <value>使用自定义图像文件</value>\n  </data>\n  <data name=\"ZoomIt_Break_BackgroundFile.Header\" xml:space=\"preserve\">\n    <value>自定义图像文件</value>\n  </data>\n  <data name=\"ZoomIt_Break_BackgroundFile_BrowseButton.Content\" xml:space=\"preserve\">\n    <value>选择</value>\n  </data>\n  <data name=\"ZoomIt_Break_BackgroundFile_Picker_Dialog_Title\" xml:space=\"preserve\">\n    <value>选择背景图片...</value>\n  </data>\n  <data name=\"FilePicker_ZoomIt_BitmapFilesFilter\" xml:space=\"preserve\">\n    <value>位图文件</value>\n  </data>\n  <data name=\"FilePicker_ZoomIt_AllPicturesFilter\" xml:space=\"preserve\">\n    <value>所有图像文件</value>\n  </data>\n  <data name=\"ZoomIt_Break_BackgroundStretch.Header\" xml:space=\"preserve\">\n    <value>拉伸填充全屏</value>\n  </data>\n  <data name=\"ZoomIt_RecordGroup.Header\" xml:space=\"preserve\">\n    <value>录屏</value>\n  </data>\n  <data name=\"ZoomIt_RecordGroup.Description\" xml:space=\"preserve\">\n    <value>按 录屏快捷键 可以开始录制全屏，再按一下 录屏快捷键 可以结束录屏。\n按 Shift+录屏快捷键 可以框选区域并录制。\n按 Alt+录屏快捷键 可以录制当前窗口。</value>\n  </data>\n  <data name=\"ZoomIt_Record_Shortcut.Header\" xml:space=\"preserve\">\n    <value>录屏快捷键</value>\n  </data>\n  <data name=\"ZoomIt_Record_Scaling.Header\" xml:space=\"preserve\">\n    <value>录屏分辨率倍率</value>\n  </data>\n  <data name=\"ZoomIt_Record_CaptureAudio.Header\" xml:space=\"preserve\">\n    <value>录制麦克风音频</value>\n  </data>\n  <data name=\"ZoomIt_Record_Microphone.Header\" xml:space=\"preserve\">\n    <value>麦克风</value>\n  </data>\n  <data name=\"ZoomIt_Record_Microphones_Default_Name\" xml:space=\"preserve\">\n    <value>默认麦克风</value>\n  </data>\n  <data name=\"ZoomIt_SnipGroup.Header\" xml:space=\"preserve\">\n    <value>截图</value>\n  </data>\n  <data name=\"ZoomIt_SnipGroup.Description\" xml:space=\"preserve\">\n    <value>按 截图快捷键 截图并复制，按 Shift+截图快捷键 截图并保存。</value>\n  </data>\n  <data name=\"ZoomIt_Snip_Shortcut.Header\" xml:space=\"preserve\">\n    <value>截图快捷键</value>\n  </data>\n  <data name=\"Oobe_ZoomIt.Description\" xml:space=\"preserve\">\n    <value>演示工具（原 ZoomIt 软件）是一个用于汇报演示的小工具，可以放大屏幕、批注、打字、截图、录屏等。</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"Oobe_ZoomIt.Title\" xml:space=\"preserve\">\n    <value>演示工具</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"Oobe_ZoomIt_HowToUse.Text\" xml:space=\"preserve\">\n    <value>在设置中启用演示工具，然后阅读各个功能的说明来进行操作。</value>\n    <comment>{Locked=\"ZoomIt\"}</comment>\n  </data>\n  <data name=\"MouseWithoutBorders_PolicyIPAddressMappingInfo.Title\" xml:space=\"preserve\">\n    <value>由您的组织所设定的规则</value>\n  </data>\n  <data name=\"MouseWithoutBorders_PolicyIPAddressMappingInfo_TextBoxControl.Description\" xml:space=\"preserve\">\n    <value>这些强制性规则无法修改、删除或禁用。</value>\n  </data>\n  <data name=\"OpenSettings.Content\" xml:space=\"preserve\">\n    <value>打开设置</value>\n  </data>\n  <data name=\"LanguageHeader.Header\" xml:space=\"preserve\">\n    <value>软件语言</value>\n  </data>\n  <data name=\"LanguageHeader.Description\" xml:space=\"preserve\">\n    <value>在汉化版中，为了防止冲突，原版简体中文包已删除，英语就是汉化包</value>\n  </data>\n  <data name=\"LanguageRestartInfo.Title\" xml:space=\"preserve\">\n    <value>重启 PowerToys 来应用新的语言</value>\n  </data>\n  <data name=\"LanguageRestartInfoButton.Content\" xml:space=\"preserve\">\n    <value>重启软件</value>\n  </data>\n  <data name=\"Default_Language\" xml:space=\"preserve\">\n    <value>系统默认</value>\n  </data>\n  <data name=\"Arabic_Saudi_Arabia_Language\" xml:space=\"preserve\">\n    <value>阿拉伯语（沙特阿拉伯）</value>\n  </data>\n  <data name=\"Czech_Language\" xml:space=\"preserve\">\n    <value>捷克语</value>\n  </data>\n  <data name=\"German_Language\" xml:space=\"preserve\">\n    <value>德语</value>\n  </data>\n  <data name=\"English_Language\" xml:space=\"preserve\">\n    <value>英语（汉化包）</value>\n  </data>\n  <data name=\"Spanish_Language\" xml:space=\"preserve\">\n    <value>西班牙语</value>\n  </data>\n  <data name=\"Persian_Farsi_Language\" xml:space=\"preserve\">\n    <value>波斯语（伊朗）</value>\n  </data>\n  <data name=\"French_Language\" xml:space=\"preserve\">\n    <value>法语</value>\n  </data>\n  <data name=\"Hebrew_Israel_Language\" xml:space=\"preserve\">\n    <value>希伯来语（以色列）</value>\n  </data>\n  <data name=\"Hungarian_Language\" xml:space=\"preserve\">\n    <value>匈牙利语</value>\n  </data>\n  <data name=\"Italian_Language\" xml:space=\"preserve\">\n    <value>意大利语</value>\n  </data>\n  <data name=\"Japanese_Language\" xml:space=\"preserve\">\n    <value>日语</value>\n  </data>\n  <data name=\"Korean_Language\" xml:space=\"preserve\">\n    <value>韩语</value>\n  </data>\n  <data name=\"Dutch_Language\" xml:space=\"preserve\">\n    <value>荷兰语</value>\n  </data>\n  <data name=\"Polish_Language\" xml:space=\"preserve\">\n    <value>波兰语</value>\n  </data>\n  <data name=\"Portuguese_Brazil_Language\" xml:space=\"preserve\">\n    <value>葡萄牙语（巴西）</value>\n  </data>\n  <data name=\"Portuguese_Portugal_Language\" xml:space=\"preserve\">\n    <value>葡萄牙语（葡萄牙）</value>\n  </data>\n  <data name=\"Russian_Language\" xml:space=\"preserve\">\n    <value>俄语</value>\n  </data>\n  <data name=\"Swedish_Language\" xml:space=\"preserve\">\n    <value>瑞典语</value>\n  </data>\n  <data name=\"Turkish_Language\" xml:space=\"preserve\">\n    <value>土耳其语</value>\n  </data>\n  <data name=\"Ukrainian_Language\" xml:space=\"preserve\">\n    <value>乌克兰语</value>\n  </data>\n  <data name=\"Chinese_Simplified_Language\" xml:space=\"preserve\">\n    <value>中文（简体）</value>\n  </data>\n  <data name=\"Chinese_Traditional_Language\" xml:space=\"preserve\">\n    <value>中文（繁体）</value>\n  </data>\n  <data name=\"GeneralPage_ViewDiagnosticDataViewerInfo.Title\" xml:space=\"preserve\">\n    <value>重启 PowerToys 生效。</value>\n  </data>\n  <data name=\"GeneralPage_ViewDiagnosticDataViewerInfoButton.Content\" xml:space=\"preserve\">\n    <value>重启</value>\n  </data>\n  <data name=\"Shell_TopLevelAdvanced.Content\" xml:space=\"preserve\">\n    <value>高级</value>\n  </data>\n  <data name=\"Shell_TopLevelFileManagement.Content\" xml:space=\"preserve\">\n    <value>文件</value>\n  </data>\n  <data name=\"Shell_TopLevelInputOutput.Content\" xml:space=\"preserve\">\n    <value>外设</value>\n  </data>\n  <data name=\"Shell_TopLevelWindowsAndLayouts.Content\" xml:space=\"preserve\">\n    <value>窗口</value>\n  </data>\n  <data name=\"Shell_TopLevelSystemTools.Content\" xml:space=\"preserve\">\n    <value>工具</value>\n  </data>\n  <data name=\"Enable_Module.[using:Microsoft.UI.Xaml.Automation]AutomationProperties.Name\" xml:space=\"preserve\">\n    <value>启用模块</value>\n  </data>\n  <data name=\"PowerLauncher_PluginVersion.Text\" xml:space=\"preserve\">\n    <value>版本</value>\n  </data>\n  <data name=\"PowerLauncher_PluginWebsite.Text\" xml:space=\"preserve\">\n    <value>项目官网</value>\n  </data>\n  <data name=\"SettingsPage_NewInfoBadge.Text\" xml:space=\"preserve\">\n    <value>新功能</value>\n\t<comment>Must be all caps</comment>\n  </data>\n</root>"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/ViewModels/CmdNotFoundViewModel.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Linq;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\n\nusing global::PowerToys.GPOWrapper;\nusing ManagedCommon;\nusing Microsoft.PowerToys.Settings.UI.Library.Helpers;\nusing Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;\nusing Microsoft.PowerToys.Settings.UI.Library.ViewModels.Commands;\nusing Microsoft.PowerToys.Telemetry;\n\nnamespace Microsoft.PowerToys.Settings.UI.ViewModels\n{\n    public class CmdNotFoundViewModel : Observable\n    {\n        public ButtonClickCommand CheckRequirementsEventHandler => new ButtonClickCommand(CheckCommandNotFoundRequirements);\n\n        public ButtonClickCommand InstallPowerShell7EventHandler => new ButtonClickCommand(InstallPowerShell7);\n\n        public ButtonClickCommand InstallWinGetClientModuleEventHandler => new ButtonClickCommand(InstallWinGetClientModule);\n\n        public ButtonClickCommand InstallModuleEventHandler => new ButtonClickCommand(InstallModule);\n\n        public ButtonClickCommand UninstallModuleEventHandler => new ButtonClickCommand(UninstallModule);\n\n        private GpoRuleConfigured _enabledGpoRuleConfiguration;\n        private bool _moduleIsGpoEnabled;\n        private bool _moduleIsGpoDisabled;\n\n        public static string AssemblyDirectory\n        {\n            get\n            {\n                string codeBase = Assembly.GetExecutingAssembly().Location;\n                UriBuilder uri = new UriBuilder(codeBase);\n                string path = Uri.UnescapeDataString(uri.Path);\n                return Path.GetDirectoryName(path);\n            }\n        }\n\n        public CmdNotFoundViewModel()\n        {\n            InitializeEnabledValue();\n        }\n\n        private void InitializeEnabledValue()\n        {\n            _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredCmdNotFoundEnabledValue();\n            _moduleIsGpoEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;\n            _moduleIsGpoDisabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled;\n\n            // Update PATH environment variable to get pwsh.exe on further calls.\n            Environment.SetEnvironmentVariable(\"PATH\", (Environment.GetEnvironmentVariable(\"PATH\", EnvironmentVariableTarget.Machine) ?? string.Empty) + \";\" + (Environment.GetEnvironmentVariable(\"PATH\", EnvironmentVariableTarget.User) ?? string.Empty), EnvironmentVariableTarget.Process);\n\n            CheckCommandNotFoundRequirements();\n        }\n\n        private string _commandOutputLog;\n\n        public string CommandOutputLog\n        {\n            get => _commandOutputLog;\n            set\n            {\n                if (_commandOutputLog != value)\n                {\n                    _commandOutputLog = value;\n                    OnPropertyChanged(nameof(CommandOutputLog));\n                }\n            }\n        }\n\n        private bool _isPowerShell7Detected;\n\n        private bool isPowerShellPreviewDetected;\n        private string powerShellPreviewPath;\n\n        public bool IsPowerShell7Detected\n        {\n            get => _isPowerShell7Detected;\n            set\n            {\n                if (_isPowerShell7Detected != value)\n                {\n                    _isPowerShell7Detected = value;\n                    OnPropertyChanged(nameof(IsPowerShell7Detected));\n                }\n            }\n        }\n\n        private bool _isWinGetClientModuleDetected;\n\n        public bool IsWinGetClientModuleDetected\n        {\n            get => _isWinGetClientModuleDetected;\n            set\n            {\n                if (_isWinGetClientModuleDetected != value)\n                {\n                    _isWinGetClientModuleDetected = value;\n                    OnPropertyChanged(nameof(IsWinGetClientModuleDetected));\n                }\n            }\n        }\n\n        private bool _isCommandNotFoundModuleInstalled;\n\n        public bool IsCommandNotFoundModuleInstalled\n        {\n            get => _isCommandNotFoundModuleInstalled;\n            set\n            {\n                if (_isCommandNotFoundModuleInstalled != value)\n                {\n                    _isCommandNotFoundModuleInstalled = value;\n                    OnPropertyChanged(nameof(IsCommandNotFoundModuleInstalled));\n                }\n            }\n        }\n\n        public bool IsModuleGpoEnabled\n        {\n            get => _moduleIsGpoEnabled;\n        }\n\n        public bool IsModuleGpoDisabled\n        {\n            get => _moduleIsGpoDisabled;\n        }\n\n        public string RunPowerShellOrPreviewScript(string powershellExecutable, string powershellArguments, bool hidePowerShellWindow = false)\n        {\n            if (isPowerShellPreviewDetected)\n            {\n                return RunPowerShellScript(Path.Combine(powerShellPreviewPath, \"pwsh-preview.cmd\"), powershellArguments, hidePowerShellWindow);\n            }\n            else\n            {\n                return RunPowerShellScript(powershellExecutable, powershellArguments, hidePowerShellWindow);\n            }\n        }\n\n        public string RunPowerShellScript(string powershellExecutable, string powershellArguments, bool hidePowerShellWindow = false)\n        {\n            string outputLog = string.Empty;\n            try\n            {\n                var startInfo = new ProcessStartInfo()\n                {\n                    FileName = powershellExecutable,\n                    Arguments = powershellArguments,\n                    CreateNoWindow = hidePowerShellWindow,\n                    UseShellExecute = false,\n                    RedirectStandardOutput = true,\n                };\n                startInfo.EnvironmentVariables[\"NO_COLOR\"] = \"1\";\n                var process = Process.Start(startInfo);\n                while (!process.StandardOutput.EndOfStream)\n                {\n                    outputLog += process.StandardOutput.ReadLine() + \"\\r\\n\"; // Weirdly, PowerShell 7 won't give us new lines.\n                }\n            }\n            catch (Exception ex)\n            {\n                outputLog = ex.ToString();\n            }\n\n            CommandOutputLog = outputLog;\n            return outputLog;\n        }\n\n        public void CheckCommandNotFoundRequirements()\n        {\n            isPowerShellPreviewDetected = false;\n            var ps1File = AssemblyDirectory + \"\\\\Assets\\\\Settings\\\\Scripts\\\\CheckCmdNotFoundRequirements.ps1\";\n            var arguments = $\"-NoProfile -NonInteractive -ExecutionPolicy Unrestricted -File \\\"{ps1File}\\\"\";\n            var result = RunPowerShellScript(\"pwsh.exe\", arguments, true);\n\n            if (result.Contains(\"已安装 PowerShell 7.4 或更高版本.\"))\n            {\n                IsPowerShell7Detected = true;\n            }\n            else if (result.Contains(\"未安装 PowerShell 7.4 或更高版本.\"))\n            {\n                IsPowerShell7Detected = false;\n            }\n            else if (result.Contains(\"pwsh.exe\"))\n            {\n                // Likely an error saying there was an error starting pwsh.exe, so we can assume Powershell 7 was not detected.\n                CommandOutputLog += \"未安装 PowerShell 7.4 或更高版本. 如需安装请访问 https://learn.microsoft.com/powershell/scripting/install/installing-powershell-on-windows \\r\\n\";\n                IsPowerShell7Detected = false;\n            }\n\n            if (!IsPowerShell7Detected)\n            {\n                // powerShell Preview might be installed, check it.\n                try\n                {\n                    // we have to search for the directory where the PowerShell preview command is located. It is added to the PATH environment variable, so we have to search for it there\n                    foreach (string pathCandidate in Environment.GetEnvironmentVariable(\"PATH\").Split(';'))\n                    {\n                        if (File.Exists(Path.Combine(pathCandidate, \"pwsh-preview.cmd\")))\n                        {\n                            result = RunPowerShellScript(Path.Combine(pathCandidate, \"pwsh-preview.cmd\"), arguments, true);\n                            if (result.Contains(\"已安装 PowerShell 7.4 或更高版本.\"))\n                            {\n                                isPowerShellPreviewDetected = true;\n                                IsPowerShell7Detected = true;\n                                powerShellPreviewPath = pathCandidate;\n                                break;\n                            }\n                        }\n                    }\n                }\n                catch (Exception)\n                {\n                    // nothing to do. No additional PowerShell installation found\n                }\n            }\n\n            if (result.Contains(\"已安装 WinGet 客户端模块.\"))\n            {\n                IsWinGetClientModuleDetected = true;\n            }\n            else if (result.Contains(\"未安装 WinGet 客户端模块.\") || result.Contains(\"WinGet 客户端模块需要更新\"))\n            {\n                IsWinGetClientModuleDetected = false;\n            }\n\n            if (result.Contains(\"已在配置文件中注册本模块.\"))\n            {\n                IsCommandNotFoundModuleInstalled = true;\n            }\n            else if (result.Contains(\"未在配置文件中注册本模块.\") || result.Contains(\"已在配置文件中注册旧版模块.\"))\n            {\n                IsCommandNotFoundModuleInstalled = false;\n            }\n\n            Logger.LogInfo(result);\n        }\n\n        public void InstallPowerShell7()\n        {\n            var ps1File = AssemblyDirectory + \"\\\\Assets\\\\Settings\\\\Scripts\\\\InstallPowerShell7.ps1\";\n            var arguments = $\"-NoProfile -ExecutionPolicy Unrestricted -File \\\"{ps1File}\\\"\";\n            var result = RunPowerShellOrPreviewScript(\"powershell.exe\", arguments);\n            if (result.Contains(\"成功安装 Powershell 7.\"))\n            {\n                IsPowerShell7Detected = true;\n            }\n\n            Logger.LogInfo(result);\n\n            // Update PATH environment variable to get pwsh.exe on further calls.\n            Environment.SetEnvironmentVariable(\"PATH\", (Environment.GetEnvironmentVariable(\"PATH\", EnvironmentVariableTarget.Machine) ?? string.Empty) + \";\" + (Environment.GetEnvironmentVariable(\"PATH\", EnvironmentVariableTarget.User) ?? string.Empty), EnvironmentVariableTarget.Process);\n        }\n\n        public void InstallWinGetClientModule()\n        {\n            var ps1File = AssemblyDirectory + \"\\\\Assets\\\\Settings\\\\Scripts\\\\InstallWinGetClientModule.ps1\";\n            var arguments = $\"-NoProfile -ExecutionPolicy Unrestricted -File \\\"{ps1File}\\\"\";\n            var result = RunPowerShellOrPreviewScript(\"pwsh.exe\", arguments);\n            if (result.Contains(\"已安装 WinGet 客户端模块.\") || result.Contains(\"已更新 WinGet 客户端模块.\"))\n            {\n                IsWinGetClientModuleDetected = true;\n            }\n            else if (result.Contains(\"未安装 WinGet 客户端模块.\"))\n            {\n                IsWinGetClientModuleDetected = false;\n            }\n\n            Logger.LogInfo(result);\n        }\n\n        public void InstallModule()\n        {\n            var ps1File = AssemblyDirectory + \"\\\\Assets\\\\Settings\\\\Scripts\\\\EnableModule.ps1\";\n            var arguments = $\"-NoProfile -ExecutionPolicy Unrestricted -File \\\"{ps1File}\\\" -scriptPath \\\"{AssemblyDirectory}\\\\..\\\"\";\n            var result = RunPowerShellOrPreviewScript(\"pwsh.exe\", arguments);\n\n            if (result.Contains(\"发现模块已经在配置文件中注册过了.\")\n                || result.Contains(\"成功在配置文件中注册模块.\")\n                || result.Contains(\"成功在配置文件中更新模块.\"))\n            {\n                IsCommandNotFoundModuleInstalled = true;\n                PowerToysTelemetry.Log.WriteEvent(new CmdNotFoundInstallEvent());\n            }\n\n            Logger.LogInfo(result);\n        }\n\n        public void UninstallModule()\n        {\n            var ps1File = AssemblyDirectory + \"\\\\Assets\\\\Settings\\\\Scripts\\\\DisableModule.ps1\";\n            var arguments = $\"-NoProfile -ExecutionPolicy Unrestricted -File \\\"{ps1File}\\\"\";\n            var result = RunPowerShellOrPreviewScript(\"pwsh.exe\", arguments);\n\n            if (result.Contains(\"已从配置文件中删除本模块.\") || result.Contains(\"配置文件中没有发现本模块, 不需要删除.\"))\n            {\n                IsCommandNotFoundModuleInstalled = false;\n                PowerToysTelemetry.Log.WriteEvent(new CmdNotFoundUninstallEvent());\n            }\n\n            Logger.LogInfo(result);\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/ViewModels/DashboardViewModel.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.IO.Abstractions;\nusing System.Linq;\nusing System.Windows.Threading;\n\nusing global::PowerToys.GPOWrapper;\nusing ManagedCommon;\nusing Microsoft.PowerToys.Settings.UI.Helpers;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Microsoft.PowerToys.Settings.UI.Library.Helpers;\nusing Microsoft.PowerToys.Settings.UI.Library.Interfaces;\nusing Microsoft.PowerToys.Settings.UI.Services;\nusing Microsoft.PowerToys.Settings.UI.Views;\nusing Microsoft.UI.Xaml;\nusing Microsoft.UI.Xaml.Controls;\n\nnamespace Microsoft.PowerToys.Settings.UI.ViewModels\n{\n    public class DashboardViewModel : Observable\n    {\n        private const string JsonFileType = \".json\";\n        private IFileSystemWatcher _watcher;\n        private DashboardModuleKBMItem _kbmItem;\n        private Dispatcher dispatcher;\n\n        public Func<string, int> SendConfigMSG { get; }\n\n        public ObservableCollection<DashboardListItem> ActiveModules { get; set; } = new ObservableCollection<DashboardListItem>();\n\n        public ObservableCollection<DashboardListItem> DisabledModules { get; set; } = new ObservableCollection<DashboardListItem>();\n\n        public bool UpdateAvailable { get; set; }\n\n        private List<DashboardListItem> _allModules;\n\n        private ISettingsRepository<GeneralSettings> _settingsRepository;\n        private GeneralSettings generalSettingsConfig;\n        private Windows.ApplicationModel.Resources.ResourceLoader resourceLoader = Helpers.ResourceLoaderInstance.ResourceLoader;\n\n        public DashboardViewModel(ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc)\n        {\n            dispatcher = Dispatcher.CurrentDispatcher;\n            _settingsRepository = settingsRepository;\n            generalSettingsConfig = settingsRepository.SettingsConfig;\n            generalSettingsConfig.AddEnabledModuleChangeNotification(ModuleEnabledChangedOnSettingsPage);\n\n            // set the callback functions value to handle outgoing IPC message.\n            SendConfigMSG = ipcMSGCallBackFunc;\n\n            _allModules = new List<DashboardListItem>();\n\n            foreach (ModuleType moduleType in Enum.GetValues(typeof(ModuleType)))\n            {\n                AddDashboardListItem(moduleType);\n            }\n\n            ActiveModules = new ObservableCollection<DashboardListItem>(_allModules.Where(x => x.IsEnabled));\n            DisabledModules = new ObservableCollection<DashboardListItem>(_allModules.Where(x => !x.IsEnabled));\n\n            UpdatingSettings updatingSettingsConfig = UpdatingSettings.LoadSettings();\n            UpdateAvailable = updatingSettingsConfig != null && (updatingSettingsConfig.State == UpdatingSettings.UpdatingState.ReadyToInstall || updatingSettingsConfig.State == UpdatingSettings.UpdatingState.ReadyToDownload);\n        }\n\n        private void AddDashboardListItem(ModuleType moduleType)\n        {\n            GpoRuleConfigured gpo = ModuleHelper.GetModuleGpoConfiguration(moduleType);\n            _allModules.Add(new DashboardListItem()\n            {\n                Tag = moduleType,\n                Label = resourceLoader.GetString(ModuleHelper.GetModuleLabelResourceName(moduleType)),\n                IsNew = moduleType == ModuleType.ZoomIt,\n                IsEnabled = gpo == GpoRuleConfigured.Enabled || (gpo != GpoRuleConfigured.Disabled && ModuleHelper.GetIsModuleEnabled(generalSettingsConfig, moduleType)),\n                IsLocked = gpo == GpoRuleConfigured.Enabled || gpo == GpoRuleConfigured.Disabled,\n                Icon = ModuleHelper.GetModuleTypeFluentIconName(moduleType),\n                EnabledChangedCallback = EnabledChangedOnUI,\n                DashboardModuleItems = GetModuleItems(moduleType),\n            });\n            if (moduleType == ModuleType.KeyboardManager && gpo != GpoRuleConfigured.Disabled)\n            {\n                KeyboardManagerSettings kbmSettings = GetKBMSettings();\n                _watcher = Library.Utilities.Helper.GetFileWatcher(KeyboardManagerSettings.ModuleName, kbmSettings.Properties.ActiveConfiguration.Value + JsonFileType, () => LoadKBMSettingsFromJson());\n            }\n        }\n\n        private void LoadKBMSettingsFromJson()\n        {\n            try\n            {\n                KeyboardManagerProfile kbmProfile = GetKBMProfile();\n                _kbmItem.RemapKeys = kbmProfile?.RemapKeys.InProcessRemapKeys;\n                _kbmItem.RemapShortcuts = KeyboardManagerViewModel.CombineShortcutLists(kbmProfile?.RemapShortcuts.GlobalRemapShortcuts, kbmProfile?.RemapShortcuts.AppSpecificRemapShortcuts);\n                dispatcher.Invoke(new Action(() => UpdateKBMItems()));\n            }\n            catch (Exception ex)\n            {\n                Logger.LogError($\"Failed to load KBM settings: {ex.Message}\");\n            }\n        }\n\n        private void UpdateKBMItems()\n        {\n            _kbmItem.NotifyPropertyChanged(nameof(_kbmItem.RemapKeys));\n            _kbmItem.NotifyPropertyChanged(nameof(_kbmItem.RemapShortcuts));\n        }\n\n        private KeyboardManagerProfile GetKBMProfile()\n        {\n            KeyboardManagerSettings kbmSettings = GetKBMSettings();\n            const string PowerToyName = KeyboardManagerSettings.ModuleName;\n            string fileName = kbmSettings.Properties.ActiveConfiguration.Value + JsonFileType;\n            return new SettingsUtils().GetSettingsOrDefault<KeyboardManagerProfile>(PowerToyName, fileName);\n        }\n\n        private KeyboardManagerSettings GetKBMSettings()\n        {\n            var settingsUtils = new SettingsUtils();\n            ISettingsRepository<KeyboardManagerSettings> moduleSettingsRepository = SettingsRepository<KeyboardManagerSettings>.GetInstance(settingsUtils);\n            return moduleSettingsRepository.SettingsConfig;\n        }\n\n        private void EnabledChangedOnUI(DashboardListItem dashboardListItem)\n        {\n            Views.ShellPage.UpdateGeneralSettingsCallback(dashboardListItem.Tag, dashboardListItem.IsEnabled);\n\n            if (dashboardListItem.Tag == ModuleType.NewPlus && dashboardListItem.IsEnabled == true)\n            {\n                var settingsUtils = new SettingsUtils();\n                var settings = NewPlusViewModel.LoadSettings(settingsUtils);\n                NewPlusViewModel.CopyTemplateExamples(settings.Properties.TemplateLocation.Value);\n            }\n        }\n\n        public void ModuleEnabledChangedOnSettingsPage()\n        {\n            try\n            {\n                ActiveModules.Clear();\n                DisabledModules.Clear();\n\n                generalSettingsConfig = _settingsRepository.SettingsConfig;\n                foreach (DashboardListItem item in _allModules)\n                {\n                    item.IsEnabled = ModuleHelper.GetIsModuleEnabled(generalSettingsConfig, item.Tag);\n                    if (item.IsEnabled)\n                    {\n                        ActiveModules.Add(item);\n                    }\n                    else\n                    {\n                        DisabledModules.Add(item);\n                    }\n                }\n\n                OnPropertyChanged(nameof(ActiveModules));\n                OnPropertyChanged(nameof(DisabledModules));\n            }\n            catch (Exception ex)\n            {\n                Logger.LogError($\"Updating active/disabled modules list failed: {ex.Message}\");\n            }\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItems(ModuleType moduleType)\n        {\n            return moduleType switch\n            {\n                ModuleType.AdvancedPaste => GetModuleItemsAdvancedPaste(),\n                ModuleType.AlwaysOnTop => GetModuleItemsAlwaysOnTop(),\n                ModuleType.Awake => GetModuleItemsAwake(),\n                ModuleType.ColorPicker => GetModuleItemsColorPicker(),\n                ModuleType.CropAndLock => GetModuleItemsCropAndLock(),\n                ModuleType.EnvironmentVariables => GetModuleItemsEnvironmentVariables(),\n                ModuleType.FancyZones => GetModuleItemsFancyZones(),\n                ModuleType.FileLocksmith => GetModuleItemsFileLocksmith(),\n                ModuleType.FindMyMouse => GetModuleItemsFindMyMouse(),\n                ModuleType.Hosts => GetModuleItemsHosts(),\n                ModuleType.ImageResizer => GetModuleItemsImageResizer(),\n                ModuleType.KeyboardManager => GetModuleItemsKeyboardManager(),\n                ModuleType.MouseHighlighter => GetModuleItemsMouseHighlighter(),\n                ModuleType.MouseJump => GetModuleItemsMouseJump(),\n                ModuleType.MousePointerCrosshairs => GetModuleItemsMousePointerCrosshairs(),\n                ModuleType.MouseWithoutBorders => GetModuleItemsMouseWithoutBorders(),\n                ModuleType.Peek => GetModuleItemsPeek(),\n                ModuleType.PowerRename => GetModuleItemsPowerRename(),\n                ModuleType.PowerLauncher => GetModuleItemsPowerLauncher(),\n                ModuleType.PowerAccent => GetModuleItemsPowerAccent(),\n                ModuleType.Workspaces => GetModuleItemsWorkspaces(),\n                ModuleType.RegistryPreview => GetModuleItemsRegistryPreview(),\n                ModuleType.MeasureTool => GetModuleItemsMeasureTool(),\n                ModuleType.ShortcutGuide => GetModuleItemsShortcutGuide(),\n                ModuleType.PowerOCR => GetModuleItemsPowerOCR(),\n                ModuleType.NewPlus => GetModuleItemsNewPlus(),\n                ModuleType.ZoomIt => GetModuleItemsZoomIt(),\n                _ => new ObservableCollection<DashboardModuleItem>(), // never called, all values listed above\n            };\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsAlwaysOnTop()\n        {\n            ISettingsRepository<AlwaysOnTopSettings> moduleSettingsRepository = SettingsRepository<AlwaysOnTopSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"AlwaysOnTop_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.Hotkey.Value.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsAwake()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = resourceLoader.GetString(\"Awake_ShortDescription\") },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsColorPicker()\n        {\n            ISettingsRepository<ColorPickerSettings> moduleSettingsRepository = SettingsRepository<ColorPickerSettings>.GetInstance(new SettingsUtils());\n            var settings = moduleSettingsRepository.SettingsConfig;\n            var hotkey = settings.Properties.ActivationShortcut;\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"ColorPicker_ShortDescription\"), Shortcut = hotkey.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsCropAndLock()\n        {\n            ISettingsRepository<CropAndLockSettings> moduleSettingsRepository = SettingsRepository<CropAndLockSettings>.GetInstance(new SettingsUtils());\n            var settings = moduleSettingsRepository.SettingsConfig;\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"CropAndLock_Thumbnail\"), Shortcut = settings.Properties.ThumbnailHotkey.Value.GetKeysList() },\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"CropAndLock_Reparent\"), Shortcut = settings.Properties.ReparentHotkey.Value.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsEnvironmentVariables()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString(\"EnvironmentVariables_LaunchButtonControl/Header\"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString(\"EnvironmentVariables_LaunchButtonControl/Description\"), ButtonGlyph = \"\\uEA37\", ButtonClickHandler = EnvironmentVariablesLaunchClicked },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsFancyZones()\n        {\n            ISettingsRepository<FancyZonesSettings> moduleSettingsRepository = SettingsRepository<FancyZonesSettings>.GetInstance(new SettingsUtils());\n            var settings = moduleSettingsRepository.SettingsConfig;\n            string activationMode = $\"{resourceLoader.GetString(settings.Properties.FancyzonesShiftDrag.Value ? \"FancyZones_ShiftDragCheckBoxControl_Header/Content\" : \"FancyZones_ActivationNoShiftDrag\")}\";\n            if (settings.Properties.FancyzonesMouseSwitch.Value)\n            {\n                activationMode += $\"；{resourceLoader.GetString(\"FancyZones_MouseDragCheckBoxControl_Header/Content\")}\";\n            }\n\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = activationMode },\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"FancyZones_OpenEditor\"), Shortcut = settings.Properties.FancyzonesEditorHotkey.Value.GetKeysList() },\n                new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString(\"FancyZones_LaunchEditorButtonControl/Header\"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString(\"FancyZones_LaunchEditorButtonControl/Description\"), ButtonGlyph = \"\\uEB3C\", ButtonClickHandler = FancyZoneLaunchClicked },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsFileLocksmith()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = resourceLoader.GetString(\"FileLocksmith_ShortDescription\") },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsFindMyMouse()\n        {\n            ISettingsRepository<FindMyMouseSettings> moduleSettingsRepository = SettingsRepository<FindMyMouseSettings>.GetInstance(new SettingsUtils());\n            string shortDescription = resourceLoader.GetString(\"FindMyMouse_ShortDescription\");\n            var settings = moduleSettingsRepository.SettingsConfig;\n            var activationMethod = settings.Properties.ActivationMethod.Value;\n            var list = new List<DashboardModuleItem>();\n            if (activationMethod == 3)\n            {\n                var hotkey = settings.Properties.ActivationShortcut;\n                list.Add(new DashboardModuleShortcutItem() { Label = shortDescription, Shortcut = hotkey.GetKeysList() });\n            }\n            else\n            {\n                switch (activationMethod)\n                {\n                    case 2: shortDescription += $\"，{resourceLoader.GetString(\"Dashboard_Activation\")}：{resourceLoader.GetString(\"MouseUtils_FindMyMouse_ActivationShakeMouse/Content\")}\"; break;\n                    case 1: shortDescription += $\"，{resourceLoader.GetString(\"Dashboard_Activation\")}：{resourceLoader.GetString(\"MouseUtils_FindMyMouse_ActivationDoubleRightControlPress/Content\")}\"; break;\n                    case 0:\n                    default: shortDescription += $\"，{resourceLoader.GetString(\"Dashboard_Activation\")}：{resourceLoader.GetString(\"MouseUtils_FindMyMouse_ActivationDoubleControlPress/Content\")}\"; break;\n                }\n\n                list.Add(new DashboardModuleTextItem() { Label = shortDescription });\n            }\n\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsHosts()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString(\"Hosts_LaunchButtonControl/Header\"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString(\"Hosts_LaunchButtonControl/Description\"), ButtonGlyph = \"\\uEA37\", ButtonClickHandler = HostLaunchClicked },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsImageResizer()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = resourceLoader.GetString(\"ImageResizer_ShortDescription\") },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsKeyboardManager()\n        {\n            KeyboardManagerProfile kbmProfile = GetKBMProfile();\n            _kbmItem = new DashboardModuleKBMItem() { RemapKeys = kbmProfile?.RemapKeys.InProcessRemapKeys, RemapShortcuts = KeyboardManagerViewModel.CombineShortcutLists(kbmProfile?.RemapShortcuts.GlobalRemapShortcuts, kbmProfile?.RemapShortcuts.AppSpecificRemapShortcuts) };\n\n            _kbmItem.RemapKeys = _kbmItem.RemapKeys.Concat(kbmProfile?.RemapKeysToText.InProcessRemapKeys).ToList();\n\n            var shortcutsToTextRemappings = KeyboardManagerViewModel.CombineShortcutLists(kbmProfile?.RemapShortcutsToText.GlobalRemapShortcuts, kbmProfile?.RemapShortcutsToText.AppSpecificRemapShortcuts);\n\n            _kbmItem.RemapShortcuts = _kbmItem.RemapShortcuts.Concat(shortcutsToTextRemappings).ToList();\n\n            var list = new List<DashboardModuleItem>\n            {\n                _kbmItem,\n                new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString(\"KeyboardManager_RemapKeyboardButton/Header\"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString(\"KeyboardManager_RemapKeyboardButton/Description\"), ButtonGlyph = \"\\uE92E\", ButtonClickHandler = KbmKeyLaunchClicked },\n                new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString(\"KeyboardManager_RemapShortcutsButton/Header\"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString(\"KeyboardManager_RemapShortcutsButton/Description\"), ButtonGlyph = \"\\uE92E\", ButtonClickHandler = KbmShortcutLaunchClicked },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsMouseHighlighter()\n        {\n            ISettingsRepository<MouseHighlighterSettings> moduleSettingsRepository = SettingsRepository<MouseHighlighterSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"MouseHighlighter_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsMouseJump()\n        {\n            ISettingsRepository<MouseJumpSettings> moduleSettingsRepository = SettingsRepository<MouseJumpSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"MouseJump_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsMousePointerCrosshairs()\n        {\n            ISettingsRepository<MousePointerCrosshairsSettings> moduleSettingsRepository = SettingsRepository<MousePointerCrosshairsSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"MouseCrosshairs_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsMouseWithoutBorders()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = resourceLoader.GetString(\"MouseWithoutBorders_ShortDescription\") },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsAdvancedPaste()\n        {\n            ISettingsRepository<AdvancedPasteSettings> moduleSettingsRepository = SettingsRepository<AdvancedPasteSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"AdvancedPasteUI_Shortcut/Header\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.AdvancedPasteUIShortcut.GetKeysList() },\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"PasteAsPlainText_Shortcut/Header\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.PasteAsPlainTextShortcut.GetKeysList() },\n            };\n\n            if (moduleSettingsRepository.SettingsConfig.Properties.PasteAsMarkdownShortcut.GetKeysList().Count > 0)\n            {\n                list.Add(new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"PasteAsMarkdown_Shortcut/Header\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.PasteAsMarkdownShortcut.GetKeysList() });\n            }\n\n            if (moduleSettingsRepository.SettingsConfig.Properties.PasteAsJsonShortcut.GetKeysList().Count > 0)\n            {\n                list.Add(new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"PasteAsJson_Shortcut/Header\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.PasteAsJsonShortcut.GetKeysList() });\n            }\n\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsPeek()\n        {\n            ISettingsRepository<PeekSettings> moduleSettingsRepository = SettingsRepository<PeekSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"Peek_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerRename()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = resourceLoader.GetString(\"PowerRename_ShortDescription\") },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerLauncher()\n        {\n            ISettingsRepository<PowerLauncherSettings> moduleSettingsRepository = SettingsRepository<PowerLauncherSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"Run_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.OpenPowerLauncher.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerAccent()\n        {\n            string shortDescription = resourceLoader.GetString(\"PowerAccent_ShortDescription\");\n            var settingsUtils = new SettingsUtils();\n            PowerAccentSettings moduleSettings = settingsUtils.GetSettingsOrDefault<PowerAccentSettings>(PowerAccentSettings.ModuleName);\n            var activationMethod = moduleSettings.Properties.ActivationKey;\n            switch (activationMethod)\n            {\n                case Library.Enumerations.PowerAccentActivationKey.LeftRightArrow: shortDescription += $\"，{resourceLoader.GetString(\"Dashboard_Activation\")}：{resourceLoader.GetString(\"QuickAccent_Activation_Key_Arrows/Content\")}\"; break;\n                case Library.Enumerations.PowerAccentActivationKey.Space: shortDescription += $\"，{resourceLoader.GetString(\"Dashboard_Activation\")}：{resourceLoader.GetString(\"QuickAccent_Activation_Key_Space/Content\")}\"; break;\n                case Library.Enumerations.PowerAccentActivationKey.Both: shortDescription += $\"，{resourceLoader.GetString(\"Dashboard_Activation\")}：{resourceLoader.GetString(\"QuickAccent_Activation_Key_Either/Content\")}\"; break;\n            }\n\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = shortDescription },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsWorkspaces()\n        {\n            ISettingsRepository<WorkspacesSettings> moduleSettingsRepository = SettingsRepository<WorkspacesSettings>.GetInstance(new SettingsUtils());\n            var settings = moduleSettingsRepository.SettingsConfig;\n\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"Workspaces_ShortDescription\"), Shortcut = settings.Properties.Hotkey.Value.GetKeysList() },\n                new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString(\"Workspaces_LaunchEditorButtonControl/Header\"), IsButtonDescriptionVisible = true, ButtonDescription = resourceLoader.GetString(\"FancyZones_LaunchEditorButtonControl/Description\"), ButtonGlyph = \"\\uEB3C\", ButtonClickHandler = WorkspacesLaunchClicked },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsRegistryPreview()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleButtonItem() { ButtonTitle = resourceLoader.GetString(\"RegistryPreview_LaunchButtonControl/Header\"), ButtonGlyph = \"\\uEA37\",  ButtonClickHandler = RegistryPreviewLaunchClicked },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsMeasureTool()\n        {\n            ISettingsRepository<MeasureToolSettings> moduleSettingsRepository = SettingsRepository<MeasureToolSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"ScreenRuler_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsShortcutGuide()\n        {\n            ISettingsRepository<ShortcutGuideSettings> moduleSettingsRepository = SettingsRepository<ShortcutGuideSettings>.GetInstance(new SettingsUtils());\n\n            var shortcut = moduleSettingsRepository.SettingsConfig.Properties.UseLegacyPressWinKeyBehavior.Value\n                ? new List<object> { 92 } // Right Windows key code\n                : moduleSettingsRepository.SettingsConfig.Properties.OpenShortcutGuide.GetKeysList();\n\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"ShortcutGuide_ShortDescription\"), Shortcut = shortcut },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsPowerOCR()\n        {\n            ISettingsRepository<PowerOcrSettings> moduleSettingsRepository = SettingsRepository<PowerOcrSettings>.GetInstance(new SettingsUtils());\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleShortcutItem() { Label = resourceLoader.GetString(\"PowerOcr_ShortDescription\"), Shortcut = moduleSettingsRepository.SettingsConfig.Properties.ActivationShortcut.GetKeysList() },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsNewPlus()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = resourceLoader.GetString(\"NewPlus_Product_Description/Description\") },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        private ObservableCollection<DashboardModuleItem> GetModuleItemsZoomIt()\n        {\n            var list = new List<DashboardModuleItem>\n            {\n                new DashboardModuleTextItem() { Label = resourceLoader.GetString(\"ZoomIt_ShortDescription\") },\n            };\n            return new ObservableCollection<DashboardModuleItem>(list);\n        }\n\n        internal void SWVersionButtonClicked()\n        {\n            NavigationService.Navigate(typeof(GeneralPage));\n        }\n\n        private void EnvironmentVariablesLaunchClicked(object sender, RoutedEventArgs e)\n        {\n            var settingsUtils = new SettingsUtils();\n            var environmentVariablesViewModel = new EnvironmentVariablesViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<EnvironmentVariablesSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, App.IsElevated);\n            environmentVariablesViewModel.Launch();\n        }\n\n        private void HostLaunchClicked(object sender, RoutedEventArgs e)\n        {\n            var settingsUtils = new SettingsUtils();\n            var hostsViewModel = new HostsViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), SettingsRepository<HostsSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, App.IsElevated);\n            hostsViewModel.Launch();\n        }\n\n        private void FancyZoneLaunchClicked(object sender, RoutedEventArgs e)\n        {\n            // send message to launch the zones editor;\n            SendConfigMSG(\"{\\\"action\\\":{\\\"FancyZones\\\":{\\\"action_name\\\":\\\"ToggledFZEditor\\\", \\\"value\\\":\\\"\\\"}}}\");\n        }\n\n        private void WorkspacesLaunchClicked(object sender, RoutedEventArgs e)\n        {\n            // send message to launch the Workspaces editor;\n            SendConfigMSG(\"{\\\"action\\\":{\\\"Workspaces\\\":{\\\"action_name\\\":\\\"LaunchEditor\\\", \\\"value\\\":\\\"\\\"}}}\");\n        }\n\n        private void KbmKeyLaunchClicked(object sender, RoutedEventArgs e)\n        {\n            var settingsUtils = new SettingsUtils();\n            var kbmViewModel = new KeyboardManagerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, KeyboardManagerPage.FilterRemapKeysList);\n            kbmViewModel.OnRemapKeyboard();\n        }\n\n        private void KbmShortcutLaunchClicked(object sender, RoutedEventArgs e)\n        {\n            var settingsUtils = new SettingsUtils();\n            var kbmViewModel = new KeyboardManagerViewModel(settingsUtils, SettingsRepository<GeneralSettings>.GetInstance(settingsUtils), ShellPage.SendDefaultIPCMessage, KeyboardManagerPage.FilterRemapKeysList);\n            kbmViewModel.OnEditShortcut();\n        }\n\n        private void RegistryPreviewLaunchClicked(object sender, RoutedEventArgs e)\n        {\n            var actionName = \"Launch\";\n            SendConfigMSG(\"{\\\"action\\\":{\\\"RegistryPreview\\\":{\\\"action_name\\\":\\\"\" + actionName + \"\\\", \\\"value\\\":\\\"\\\"}}}\");\n        }\n\n        internal void DashboardListItemClick(object sender)\n        {\n            Button button = sender as Button;\n            if (button == null)\n            {\n                return;\n            }\n\n            if (!(button.Tag is ModuleType))\n            {\n                return;\n            }\n\n            ModuleType moduleType = (ModuleType)button.Tag;\n\n            NavigationService.Navigate(ModuleHelper.GetModulePageType(moduleType));\n        }\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI/ViewModels/PowerAccentViewModel.cs",
    "content": "// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing global::PowerToys.GPOWrapper;\nusing Microsoft.PowerToys.Settings.UI.Helpers;\nusing Microsoft.PowerToys.Settings.UI.Library;\nusing Microsoft.PowerToys.Settings.UI.Library.Enumerations;\nusing Microsoft.PowerToys.Settings.UI.Library.Helpers;\nusing Microsoft.PowerToys.Settings.UI.Library.Interfaces;\n\nnamespace Microsoft.PowerToys.Settings.UI.ViewModels\n{\n    public class PowerAccentViewModel : Observable\n    {\n        private GeneralSettings GeneralSettingsConfig { get; set; }\n\n        private readonly PowerAccentSettings _powerAccentSettings;\n\n        private readonly ISettingsUtils _settingsUtils;\n\n        private const string SpecialGroup = \"QuickAccent_Group_Special\";\n        private const string LanguageGroup = \"QuickAccent_Group_Language\";\n\n        public List<PowerAccentLanguageModel> Languages { get; } = [\n            new PowerAccentLanguageModel(\"SPECIAL\", \"QuickAccent_SelectedLanguage_Special\", SpecialGroup),\n            new PowerAccentLanguageModel(\"BG\", \"QuickAccent_SelectedLanguage_Bulgarian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"CA\", \"QuickAccent_SelectedLanguage_Catalan\", LanguageGroup),\n            new PowerAccentLanguageModel(\"CRH\", \"QuickAccent_SelectedLanguage_Crimean\", LanguageGroup),\n            new PowerAccentLanguageModel(\"CUR\", \"QuickAccent_SelectedLanguage_Currency\", SpecialGroup),\n            new PowerAccentLanguageModel(\"HR\", \"QuickAccent_SelectedLanguage_Croatian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"CZ\", \"QuickAccent_SelectedLanguage_Czech\", LanguageGroup),\n            new PowerAccentLanguageModel(\"DK\", \"QuickAccent_SelectedLanguage_Danish\", LanguageGroup),\n            new PowerAccentLanguageModel(\"GA\", \"QuickAccent_SelectedLanguage_Gaeilge\", LanguageGroup),\n            new PowerAccentLanguageModel(\"GD\", \"QuickAccent_SelectedLanguage_Gaidhlig\", LanguageGroup),\n            new PowerAccentLanguageModel(\"NL\", \"QuickAccent_SelectedLanguage_Dutch\", LanguageGroup),\n            new PowerAccentLanguageModel(\"EL\", \"QuickAccent_SelectedLanguage_Greek\", LanguageGroup),\n            new PowerAccentLanguageModel(\"EST\", \"QuickAccent_SelectedLanguage_Estonian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"EPO\", \"QuickAccent_SelectedLanguage_Esperanto\", LanguageGroup),\n            new PowerAccentLanguageModel(\"FI\", \"QuickAccent_SelectedLanguage_Finnish\", LanguageGroup),\n            new PowerAccentLanguageModel(\"FR\", \"QuickAccent_SelectedLanguage_French\", LanguageGroup),\n            new PowerAccentLanguageModel(\"DE\", \"QuickAccent_SelectedLanguage_German\", LanguageGroup),\n            new PowerAccentLanguageModel(\"HE\", \"QuickAccent_SelectedLanguage_Hebrew\", LanguageGroup),\n            new PowerAccentLanguageModel(\"HU\", \"QuickAccent_SelectedLanguage_Hungarian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"IS\", \"QuickAccent_SelectedLanguage_Icelandic\", LanguageGroup),\n            new PowerAccentLanguageModel(\"IPA\", \"QuickAccent_SelectedLanguage_IPA\", SpecialGroup),\n            new PowerAccentLanguageModel(\"IT\", \"QuickAccent_SelectedLanguage_Italian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"KU\", \"QuickAccent_SelectedLanguage_Kurdish\", LanguageGroup),\n            new PowerAccentLanguageModel(\"LT\", \"QuickAccent_SelectedLanguage_Lithuanian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"MK\", \"QuickAccent_SelectedLanguage_Macedonian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"MI\", \"QuickAccent_SelectedLanguage_Maori\", LanguageGroup),\n            new PowerAccentLanguageModel(\"NO\", \"QuickAccent_SelectedLanguage_Norwegian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"PI\", \"QuickAccent_SelectedLanguage_Pinyin\", LanguageGroup),\n            new PowerAccentLanguageModel(\"PIE\", \"QuickAccent_SelectedLanguage_Proto_Indo_European\", LanguageGroup),\n            new PowerAccentLanguageModel(\"PL\", \"QuickAccent_SelectedLanguage_Polish\", LanguageGroup),\n            new PowerAccentLanguageModel(\"PT\", \"QuickAccent_SelectedLanguage_Portuguese\", LanguageGroup),\n            new PowerAccentLanguageModel(\"RO\", \"QuickAccent_SelectedLanguage_Romanian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"ROM\", \"QuickAccent_SelectedLanguage_Romanization\", SpecialGroup),\n            new PowerAccentLanguageModel(\"SK\", \"QuickAccent_SelectedLanguage_Slovak\", LanguageGroup),\n            new PowerAccentLanguageModel(\"SL\", \"QuickAccent_SelectedLanguage_Slovenian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"SP\", \"QuickAccent_SelectedLanguage_Spanish\", LanguageGroup),\n            new PowerAccentLanguageModel(\"SR\", \"QuickAccent_SelectedLanguage_Serbian\", LanguageGroup),\n            new PowerAccentLanguageModel(\"SR_CYRL\", \"QuickAccent_SelectedLanguage_Serbian_Cyrillic\", LanguageGroup),\n            new PowerAccentLanguageModel(\"SV\", \"QuickAccent_SelectedLanguage_Swedish\", LanguageGroup),\n            new PowerAccentLanguageModel(\"TK\", \"QuickAccent_SelectedLanguage_Turkish\", LanguageGroup),\n            new PowerAccentLanguageModel(\"CY\", \"QuickAccent_SelectedLanguage_Welsh\", LanguageGroup),\n        ];\n\n        public PowerAccentLanguageGroupModel[] LanguageGroups { get; private set; }\n\n        private readonly string[] _toolbarOptions =\n        {\n            \"Top center\",\n            \"Bottom center\",\n            \"Left\",\n            \"Right\",\n            \"Top right corner\",\n            \"Top left corner\",\n            \"Bottom right corner\",\n            \"Bottom left corner\",\n            \"Center\",\n        };\n\n        private Func<string, int> SendConfigMSG { get; }\n\n        public PowerAccentViewModel(ISettingsUtils settingsUtils, ISettingsRepository<GeneralSettings> settingsRepository, Func<string, int> ipcMSGCallBackFunc)\n        {\n            // To obtain the general settings configurations of PowerToys Settings.\n            ArgumentNullException.ThrowIfNull(settingsRepository);\n\n            _settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));\n            GeneralSettingsConfig = settingsRepository.SettingsConfig;\n\n            InitializeEnabledValue();\n            InitializeLanguages();\n\n            if (_settingsUtils.SettingsExists(PowerAccentSettings.ModuleName))\n            {\n                _powerAccentSettings = _settingsUtils.GetSettingsOrDefault<PowerAccentSettings>(PowerAccentSettings.ModuleName);\n            }\n            else\n            {\n                _powerAccentSettings = new PowerAccentSettings();\n            }\n\n            _inputTimeMs = _powerAccentSettings.Properties.InputTime.Value;\n\n            _excludedApps = _powerAccentSettings.Properties.ExcludedApps.Value;\n\n            if (!string.IsNullOrWhiteSpace(_powerAccentSettings.Properties.SelectedLang.Value) && !_powerAccentSettings.Properties.SelectedLang.Value.Contains(\"ALL\"))\n            {\n                SelectedLanguageOptions = _powerAccentSettings.Properties.SelectedLang.Value.Split(',')\n                   .Select(l => Languages.Find(lang => lang.LanguageCode == l))\n                   .Where(l => l != null) // Wrongly typed languages will appear as null after find. We want to remove those to avoid crashes.\n                   .ToArray();\n            }\n            else if (_powerAccentSettings.Properties.SelectedLang.Value.Contains(\"ALL\"))\n            {\n                SelectedLanguageOptions = Languages.ToArray();\n            }\n            else\n            {\n                SelectedLanguageOptions = Array.Empty<PowerAccentLanguageModel>();\n            }\n\n            _toolbarPositionIndex = Array.IndexOf(_toolbarOptions, _powerAccentSettings.Properties.ToolbarPosition.Value);\n\n            // set the callback functions value to handle outgoing IPC message.\n            SendConfigMSG = ipcMSGCallBackFunc;\n        }\n\n        private void InitializeEnabledValue()\n        {\n            _enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredQuickAccentEnabledValue();\n            if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)\n            {\n                // Get the enabled state from GPO.\n                _enabledStateIsGPOConfigured = true;\n                _isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;\n            }\n            else\n            {\n                _isEnabled = GeneralSettingsConfig.Enabled.PowerAccent;\n            }\n        }\n\n        /// <summary>\n        /// Adds Localized Language Name, sorts by it and splits languages into two groups.\n        /// </summary>\n        private void InitializeLanguages()\n        {\n            foreach (var item in Languages)\n            {\n                item.Language = ResourceLoaderInstance.ResourceLoader.GetString(item.LanguageResourceID);\n            }\n\n#pragma warning disable CA1309 // 使用序数字符串比较\n            Languages.Sort((x, y) => string.Compare(x.Language, y.Language, StringComparison.CurrentCulture));\n#pragma warning restore CA1309 // 使用序数字符串比较\n            LanguageGroups = Languages\n                .GroupBy(language => language.GroupResourceID)\n                .Select(grp => new PowerAccentLanguageGroupModel(grp.ToList(), ResourceLoaderInstance.ResourceLoader.GetString(grp.Key)))\n                .ToArray();\n        }\n\n        public bool IsEnabled\n        {\n            get => _isEnabled;\n            set\n            {\n                if (_enabledStateIsGPOConfigured)\n                {\n                    // If it's GPO configured, shouldn't be able to change this state.\n                    return;\n                }\n\n                if (_isEnabled != value)\n                {\n                    _isEnabled = value;\n\n                    GeneralSettingsConfig.Enabled.PowerAccent = value;\n                    OnPropertyChanged(nameof(IsEnabled));\n                    OutGoingGeneralSettings outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);\n                    SendConfigMSG(outgoing.ToString());\n                }\n            }\n        }\n\n        public bool IsEnabledGpoConfigured\n        {\n            get => _enabledStateIsGPOConfigured;\n        }\n\n        public int ActivationKey\n        {\n            get\n            {\n                return (int)_powerAccentSettings.Properties.ActivationKey;\n            }\n\n            set\n            {\n                if (value != (int)_powerAccentSettings.Properties.ActivationKey)\n                {\n                    _powerAccentSettings.Properties.ActivationKey = (PowerAccentActivationKey)value;\n                    OnPropertyChanged(nameof(ActivationKey));\n                    RaisePropertyChanged();\n                }\n            }\n        }\n\n        public bool DoNotActivateOnGameMode\n        {\n            get\n            {\n                return _powerAccentSettings.Properties.DoNotActivateOnGameMode;\n            }\n\n            set\n            {\n                if (value != _powerAccentSettings.Properties.DoNotActivateOnGameMode)\n                {\n                    _powerAccentSettings.Properties.DoNotActivateOnGameMode = value;\n                    OnPropertyChanged(nameof(DoNotActivateOnGameMode));\n                    RaisePropertyChanged();\n                }\n            }\n        }\n\n        private int _inputTimeMs = PowerAccentSettings.DefaultInputTimeMs;\n\n        public int InputTimeMs\n        {\n            get\n            {\n                return _inputTimeMs;\n            }\n\n            set\n            {\n                if (value != _inputTimeMs)\n                {\n                    _inputTimeMs = value;\n                    _powerAccentSettings.Properties.InputTime.Value = value;\n                    OnPropertyChanged(nameof(InputTimeMs));\n                    RaisePropertyChanged();\n                }\n            }\n        }\n\n        private string _excludedApps;\n\n        public string ExcludedApps\n        {\n            get\n            {\n                return _excludedApps;\n            }\n\n            set\n            {\n                if (value != _excludedApps)\n                {\n                    _excludedApps = value;\n                    _powerAccentSettings.Properties.ExcludedApps.Value = value;\n                    OnPropertyChanged(nameof(ExcludedApps));\n                    RaisePropertyChanged();\n                }\n            }\n        }\n\n        private int _toolbarPositionIndex;\n\n        public int ToolbarPositionIndex\n        {\n            get\n            {\n                return _toolbarPositionIndex;\n            }\n\n            set\n            {\n                if (_toolbarPositionIndex != value)\n                {\n                    _toolbarPositionIndex = value;\n                    _powerAccentSettings.Properties.ToolbarPosition.Value = _toolbarOptions[value];\n                    RaisePropertyChanged(nameof(ToolbarPositionIndex));\n                }\n            }\n        }\n\n        public bool AllSelected => _selectedLanguageOptions.Length == Languages.Count;\n\n        private PowerAccentLanguageModel[] _selectedLanguageOptions;\n\n        public PowerAccentLanguageModel[] SelectedLanguageOptions\n        {\n            get => _selectedLanguageOptions;\n            set\n            {\n                _selectedLanguageOptions = value;\n                _powerAccentSettings.Properties.SelectedLang.Value = string.Join(',', _selectedLanguageOptions.Select(l => l.LanguageCode));\n                RaisePropertyChanged(nameof(SelectedLanguageOptions));\n            }\n        }\n\n        public bool ShowUnicodeDescription\n        {\n            get\n            {\n                return _powerAccentSettings.Properties.ShowUnicodeDescription;\n            }\n\n            set\n            {\n                if (value != _powerAccentSettings.Properties.ShowUnicodeDescription)\n                {\n                    _powerAccentSettings.Properties.ShowUnicodeDescription = value;\n                    OnPropertyChanged(nameof(ShowUnicodeDescription));\n                    RaisePropertyChanged();\n                }\n            }\n        }\n\n        public bool SortByUsageFrequency\n        {\n            get\n            {\n                return _powerAccentSettings.Properties.SortByUsageFrequency;\n            }\n\n            set\n            {\n                if (value != _powerAccentSettings.Properties.SortByUsageFrequency)\n                {\n                    _powerAccentSettings.Properties.SortByUsageFrequency = value;\n                    OnPropertyChanged(nameof(SortByUsageFrequency));\n                    RaisePropertyChanged();\n                }\n            }\n        }\n\n        public bool StartSelectionFromTheLeft\n        {\n            get\n            {\n                return _powerAccentSettings.Properties.StartSelectionFromTheLeft;\n            }\n\n            set\n            {\n                if (value != _powerAccentSettings.Properties.StartSelectionFromTheLeft)\n                {\n                    _powerAccentSettings.Properties.StartSelectionFromTheLeft = value;\n                    OnPropertyChanged(nameof(StartSelectionFromTheLeft));\n                    RaisePropertyChanged();\n                }\n            }\n        }\n\n        private void RaisePropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            // Notify UI of property change\n            OnPropertyChanged(propertyName);\n\n            if (SendConfigMSG != null)\n            {\n                SndPowerAccentSettings snd = new SndPowerAccentSettings(_powerAccentSettings);\n                SndModuleSettings<SndPowerAccentSettings> ipcMessage = new SndModuleSettings<SndPowerAccentSettings>(snd);\n                SendConfigMSG(ipcMessage.ToJsonString());\n            }\n        }\n\n        public void RefreshEnabledState()\n        {\n            InitializeEnabledValue();\n            OnPropertyChanged(nameof(IsEnabled));\n        }\n\n        private GpoRuleConfigured _enabledGpoRuleConfiguration;\n        private bool _enabledStateIsGPOConfigured;\n        private bool _isEnabled;\n    }\n}\n"
  },
  {
    "path": "PowerToys/src/settings-ui/Settings.UI.Library/ColorFormatModel.cs",
    "content": "﻿// Copyright (c) Microsoft Corporation\n// The Microsoft Corporation licenses this file to you under the MIT license.\n// See the LICENSE file in the project root for more information.\n\nusing System.ComponentModel;\nusing System.Runtime.CompilerServices;\n\nusing ManagedCommon;\n\nnamespace Microsoft.PowerToys.Settings.UI.Library\n{\n    public class ColorFormatModel : INotifyPropertyChanged\n    {\n        private string _name;\n        private string _format;\n        private bool _isShown;\n        private bool _canMoveUp = true;\n        private bool _canMoveDown = true;\n        private bool _canBeDeleted = true;\n        private bool _isNew;\n        private bool _isValid = true;\n\n        public ColorFormatModel(string name, string format, bool isShown)\n        {\n            Name = name;\n            Format = format;\n            IsShown = isShown;\n            IsNew = false;\n        }\n\n        public ColorFormatModel()\n        {\n            Format = \"自定义 (R = %Re, G = %Gr, B = %Bl)\";\n            IsShown = true;\n            IsNew = true;\n        }\n\n        public string Name\n        {\n            get\n            {\n                return _name;\n            }\n\n            set\n            {\n                _name = value;\n                OnPropertyChanged(nameof(Name));\n            }\n        }\n\n        public string Format\n        {\n            get\n            {\n                return _format;\n            }\n\n            set\n            {\n                _format = value;\n                OnPropertyChanged(nameof(Format));\n                OnPropertyChanged(nameof(Example));\n            }\n        }\n\n        public bool IsShown\n        {\n            get\n            {\n                return _isShown;\n            }\n\n            set\n            {\n                _isShown = value;\n                OnPropertyChanged(nameof(IsShown));\n            }\n        }\n\n        public bool CanMoveUp\n        {\n            get\n            {\n                return _canMoveUp;\n            }\n\n            set\n            {\n                if (value != _canMoveUp)\n                {\n                    _canMoveUp = value;\n                    OnPropertyChanged(nameof(CanMoveUp));\n                }\n            }\n        }\n\n        public bool CanMoveDown\n        {\n            get\n            {\n                return _canMoveDown;\n            }\n\n            set\n            {\n                if (value != _canMoveDown)\n                {\n                    _canMoveDown = value;\n                    OnPropertyChanged(nameof(CanMoveDown));\n                }\n            }\n        }\n\n        public bool CanBeDeleted\n        {\n            get\n            {\n                return _canBeDeleted;\n            }\n\n            set\n            {\n                if (value != _canBeDeleted)\n                {\n                    _canBeDeleted = value;\n                    OnPropertyChanged(nameof(CanBeDeleted));\n                }\n            }\n        }\n\n        public bool IsNew\n        {\n            get\n            {\n                return _isNew;\n            }\n\n            set\n            {\n                _isNew = value;\n                OnPropertyChanged(nameof(IsNew));\n            }\n        }\n\n        public bool IsValid\n        {\n            get\n            {\n                return _isValid;\n            }\n\n            set\n            {\n                _isValid = value;\n                OnPropertyChanged(nameof(IsValid));\n            }\n        }\n\n        public string Example\n        {\n            get\n            {\n                // get string representation in 2 steps. First replace all color specific number values then in 2nd step replace color name with localisation\n                return Helpers.ColorNameHelper.ReplaceName(ColorFormatHelper.GetStringRepresentation(null, _format), null);\n            }\n\n            set\n            {\n            }\n        }\n\n        public event PropertyChangedEventHandler PropertyChanged;\n\n        private void OnPropertyChanged([CallerMemberName] string propertyName = null)\n        {\n            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));\n        }\n    }\n}\n"
  },
  {
    "path": "README.md",
    "content": "# PowerToys Simplified Chinese Translation\r\n\r\n<img src=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/PowerToysCN-23.topic.png\"/>\r\n\r\nPowerToys 简体中文翻译优化补丁\r\n\r\n根据日常使用习惯修改，做说人话的翻译。\r\n\r\n- 反馈汉化问题：[议题](https://github.com/zetaloop/PowerToys-CN/issues) 或 zetaloop@outlook.com\r\n\r\n- 版本：23.0 for **PowerToys v0.88.0**\r\n\r\n- 现已支持 x64 & ARM64（ARM64 需自行编译）\r\n\r\n下载 原版安装包：[PowerToys](https://github.com/microsoft/PowerToys)\r\n\r\n下载 汉化包：[Github Release](https://github.com/zetaloop/PowerToys-CN/releases/latest) | [蓝奏云 密码zeta](https://zeta.lanzouq.com/b0nyvf3yb)\r\n\r\n## 使用方法\r\n\r\n① 安装原版 PowerToys 软件：\r\n\r\n　　下载 .exe 安装包，安装 PowerToys 软件\r\n\r\n② 安装优化补丁包：\r\n\r\n　　下载 PowerToysCN-汉化版本号.7z，解压后运行“安装.CMD”，根据提示确定安装\r\n\r\n## 展示\r\n你可以切换浏览器的亮色/暗色模式来查看两种模式的截图噢~\r\n\r\n<picture>\r\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/4bs.png\">\r\n  <img src=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/4ws.png\" />\r\n</picture>\r\n<picture>\r\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/1bs.png\">\r\n  <img src=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/1ws.png\" />\r\n</picture>\r\n<picture>\r\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/2bs.png\">\r\n  <img src=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/2ws.png\" />\r\n</picture>\r\n<picture>\r\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/3bs.png\">\r\n  <img src=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/3ws.png\" />\r\n</picture>\r\n<picture>\r\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/5bs.png\">\r\n  <img src=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/5ws.png\" />\r\n</picture>\r\n<picture>\r\n  <source media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/6bs.png\">\r\n  <img src=\"https://raw.gitmirror.com/zetaloop/PowerToys-CN/master/to.pic/6ws.png\" />\r\n</picture>\r\n\r\n\r\nPowerToys 分组：工具 窗口 外设 文件 高级\r\n\r\nPowerToys 模块名称：高级粘贴 窗口置顶 阻止睡眠 取色器 未找到命令 窗口镜像 环境变量 窗口布局 预览增强 文件开锁匠 域名表 图像裁剪器 键盘修改器 鼠标工具箱 无界鼠标 新建+ 快速查看 批量重命名 快捷启动器 字母助手 注册表预览 屏幕标尺 快捷键指南 文本提取 ~~直播工具~~ 工作区 演示工具\r\n\r\nPowerToys 常规设置、主页（仪表盘）、快捷面板、Monaco 文本编辑器组件、各模块预设及设置界面、实验功能已移除测试组限制\r\n\r\nPowerToys 入门指南\r\n\r\nPowerToys 运行信息、提示消息、状态栏菜单\r\n\r\nAdvanced Paste 操作界面\r\n\r\nAwake 操作界面、状态栏菜单\r\n\r\nAlways on Top 提示\r\n\r\nColor Picker 操作界面\r\n\r\nCommand Not Found 命令文件\r\n\r\nCrop And Lock 窗口标题\r\n\r\nEnvironment Variables 操作界面\r\n\r\nFancyZones 操作界面\r\n\r\nFile Explorer add-ons 操作界面、预览器错误提示\r\n\r\nFile Locksmith 操作界面、右键菜单\r\n\r\nHosts File Editor 操作界面\r\n\r\nImage Resizer 操作界面、右键菜单\r\n\r\nKeyboard Manager 操作界面\r\n\r\nMouse Without Borders 原版软件界面、通知消息、执行脚本、大小限制100MB改为500MB超时30s改为60s\r\n\r\nNew+ 右键菜单、Win10 右键菜单、模板文件\r\n\r\nPeek 操作界面\r\n\r\nPowerRename 操作界面、右键菜单\r\n\r\nPowerToys Run 操作界面、一大堆插件的中文适配\r\n\r\nRegistry Preview 操作界面\r\n\r\nScreen Ruler 操作界面\r\n\r\nShortcut Guide 操作界面、快捷键图片\r\n\r\nText Extractor 操作界面\r\n\r\n~~Video Conference Mute 按键图片、虚拟摄像头设备名称~~（已被移除）\r\n\r\nWorkspaces 操作界面\r\n\r\nZoom It 原版软件界面、弹窗消息\r\n\r\n## 星标趋势\r\n\r\n[![Stargazers over time](https://starchart.cc/zetaloop/PowerToys-CN.svg?variant=adaptive)](https://starchart.cc/zetaloop/PowerToys-CN)\r\n"
  },
  {
    "path": "Tools/README.md",
    "content": "# Deprecated.\n\n`autosort.py`: PowerToys Quick Accent now sorts language lists using the system locale, eliminating the need for manual pinyin sorting.\n\n`modify.cmd`: The VSCodeWorkspace issue has been resolved, and VideoConference has been removed, making this batch file obsolete.\n\n`clean.cmd`: Instead of maintaining this batch file, simply keep a clean copy before building.\n"
  },
  {
    "path": "Tools/autosort.py",
    "content": "import os\nimport pinyin\n\n# 设置翻译文件所在的目录路径以及一些必要的初始化变量\ntranslations_directory = os.path.dirname(__file__)  # os.getcwd()\ntranslations_directory = os.path.abspath(os.path.join(translations_directory, \"..\\\\..\"))\ntranslations_directory = translations_directory.replace(\"\\\\\", \"/\")  # 设置为当前目录的上一级目录\nprint(translations_directory)\ninitial_languages = [\"All\", \"IPA\", \"Currency\", \"Pinyin\"]\nos.chdir(translations_directory)\n\n\ndef main():\n    \"\"\"主函数，完成全部工作流程\"\"\"\n    versions = get_power_toys_versions()  # 获取所有版本\n    latest_version = get_latest_version(versions)  # 获取最新版本\n    lab2cn, lab2view, lab2model = initall(latest_version)  # 获取翻译和需要替换的内容\n    sortedlab2cn = sort_label(lab2cn)  # 将翻译排序\n    print(\"\\n[排序完成]\")\n    for i in lab2cn:\n        print(f\"{i} >>> {lab2cn[i]}\")  # 打印排序后的翻译\n    input(\"\\n[按任意键立即写入]\")\n    replace_translations_in_file(\n        \"SettingsXAML/Views/PowerAccentPage.xaml\", lab2cn, sortedlab2cn, lab2view\n    )  # 在文件中替换翻译\n    replace_translations_in_file(\n        \"ViewModels/PowerAccentViewModel.cs\", lab2cn, sortedlab2cn, lab2model\n    )  # 在文件中替换翻译\n    print(\"OK.\\n\")\n    input(\"[按任意键退出...]\")  # 等待用户操作后退出\n\n\ndef get_power_toys_versions():\n    \"\"\"获取指定目录下所有的 PowerToys 版本\"\"\"\n    versions = sorted(\n        i for i in os.listdir() if i.startswith(\"PowerToys-\") and i[-1].isdigit()\n    )\n    print(f'发现版本：{\", \".join(versions)}')\n    return versions  # 返回所有版本\n\n\ndef get_latest_version(versions):\n    \"\"\"获取最新的 PowerToys 版本\"\"\"\n    try:\n        latest_version = versions[-1]  # 尝试获取最新的版本\n        print(f\"选定版本：{latest_version}\\n\")\n        return latest_version  # 返回最新版本\n    except IndexError:\n        print(\"无可用版本！\")\n        input(\"[按任意键退出...]\")\n        exit()  # 如果没有可用版本，退出程序\n\n\ndef initall(latest_version):\n    \"\"\"获取给定版本的翻译数据和需要替换的数据\"\"\"\n    os.chdir(latest_version)\n    os.chdir(\"src/settings-ui/Settings.UI\")\n\n    LABELS = []  # 标签，RESC顺序\n    NAMESCN = []  # 中文，RESC顺序\n    VLABLES = []  # 标签，View顺序\n    VIEWS_ln = []  # View行\n    MODELS_ln = []  # ViewModel行\n    with open(\"Strings/en-us/Resources.resw\", encoding=\"utf-8\") as f:\n        lines = f.readlines()\n        for i, line in enumerate(lines):\n            if \"QuickAccent_SelectedLanguage_\" in line:\n                LABELS.append(\n                    line.split(\"SelectedLanguage_\")[-1].split(\".Content\")[0]\n                )  # 读取原始标签\n                NAMESCN.append(\n                    lines[i + 1].split(\"<value>\")[-1].split(\"</value>\")[0]\n                )  # 读取翻译\n                print(f\"RESC {LABELS[-1]} >>> {NAMESCN[-1]}\")\n\n    with open(\"SettingsXAML/Views/PowerAccentPage.xaml\", encoding=\"utf-8\") as f:\n        lines = f.readlines()\n        for line in lines:\n            if \"QuickAccent_SelectedLanguage_\" in line:\n                VIEWS_ln.append(line)  # 读取View\n                VLABLES.append(line.split(\"SelectedLanguage_\")[-1].split('\"')[0])\n                print(f\"VIEW {VLABLES[-1]} ==> {line.strip()}\")\n\n    with open(\"ViewModels/PowerAccentViewModel.cs\", encoding=\"utf-8\") as f:\n        lines = f.readlines()\n        for line in lines:\n            if 4 < len(line.strip()) < 7 and line.upper() == line:\n                MODELS_ln.append(line)  # 读取ViewModel\n                print(f\"VIEW {VLABLES[len(MODELS_ln)-1]} ==> {line.strip()}\")\n    return (\n        dict(zip(LABELS, NAMESCN)),\n        dict(zip(VLABLES, VIEWS_ln)),\n        dict(zip(VLABLES, MODELS_ln)),\n    )  # 返回原始文本与翻译的映射，以及需要替换的内容\n\n\ndef sort_label(dic):\n    \"\"\"将翻译按照拼音排序\"\"\"\n    sorted_translations = sorted(\n        (pinyin.get(cn, format=\"strip\"), lab) for lab, cn in dic.items()\n    )\n    lst = [\"All\", \"IPA\", \"Currency\", \"Pinyin\"]\n    lst += [\n        original_text\n        for _, original_text in sorted_translations\n        if original_text not in lst\n    ]\n    return {x: dic[x] for x in lst}\n\n\ndef replace_translations_in_file(file_path, lab2cn, sortedlab2cn, lab2xx):\n    \"\"\"在给定文件中替换原始文本为翻译后的文本\"\"\"\n    with open(file_path, encoding=\"utf-8\") as f:\n        content = f.read()  # 读取文件内容\n    temp = [\n        f\"00{i}\"[-3:] + \"XXXXAUTOTRANSLATIONXXXX\" for i in range(len(lab2xx))\n    ]  # 生成临时替换文本\n    temp2lab = {tmp: txt for tmp, txt in zip(temp, lab2xx)}\n    lab2sortedlab = {txt: sor for txt, sor in zip(lab2xx, sortedlab2cn)}\n    temp2xx = {tmp: lab2xx[lab2sortedlab[temp2lab[tmp]]] for tmp in temp}\n\n    for original, tmp in zip(lab2xx.values(), temp):\n        content = content.replace(original, tmp)\n    for tmp in temp:\n        content = content.replace(tmp, temp2xx[tmp])\n    # print(f\"■■■■■■content: {content}■■■■■■\")\n    with open(file_path, \"w\", encoding=\"utf-8\") as f:\n        f.write(content)  # 写回文件\n\n\nif __name__ == \"__main__\":\n    main()  # 如果是作为脚本运行，调用 main 函数\n"
  },
  {
    "path": "Tools/autosort_newgptbroken.py",
    "content": "import os\nimport pinyin\n\n# 设置翻译文件所在的目录路径以及一些必要的初始化变量\ntranslations_directory = os.path.abspath(os.path.join(os.getcwd(), '..')).replace('\\\\','/')  # 设置为当前目录的上一级目录\ninitial_languages = ['All', 'Currency', 'Pinyin']\nos.chdir(translations_directory)\n\ndef get_power_toys_versions():\n    \"\"\"获取指定目录下所有的 PowerToys 版本\"\"\"\n    versions = sorted(i for i in os.listdir() if i.startswith('PowerToys-') and i[-1].isdigit())\n    print(f'发现版本：{\", \".join(versions)}')\n    return versions  # 返回所有版本\n\ndef get_latest_version(versions):\n    \"\"\"获取最新的 PowerToys 版本\"\"\"\n    try:\n        latest_version = versions[-1]  # 尝试获取最新的版本\n        print(f'选定版本：{latest_version}')\n        return latest_version  # 返回最新版本\n    except IndexError:\n        print('无可用版本！')\n        input('[按任意键退出...]')\n        exit()  # 如果没有可用版本，退出程序\n\ndef get_translations_and_replacements(latest_version):\n    \"\"\"获取给定版本的翻译数据和需要替换的数据\"\"\"\n    os.chdir(latest_version)\n    os.chdir('src/settings-ui/Settings.UI')\n\n    original_texts = []  # 保存原始文本\n    translations = []  # 保存翻译文本\n    replacements_in_view = []  # 保存需要在视图中替换的内容\n    replacements_in_model = []  # 保存需要在模型中替换的内容\n    read_next_line = False  # 用于标识是否读取下一行\n    with open('Strings/en-us/Resources.resw', encoding='utf-8') as f:\n        lines = f.readlines()\n\n    for line in lines:\n        if read_next_line:\n            translations.append(line.split('<value>')[-1].split('</value>')[0])  # 读取翻译\n            read_next_line = False\n        if 'QuickAccent_SelectedLanguage_' in line:\n            original_texts.append(line.split('SelectedLanguage_')[-1].split('.Content')[0])  # 读取原始文本\n            read_next_line = True\n\n    with open('Views/PowerAccentPage.xaml', encoding='utf-8') as f:\n        lines = f.readlines()\n        for line in lines:\n            if 'QuickAccent_SelectedLanguage_' in line:\n                replacements_in_view.append(line)  # 保存需要在视图中替换的内容\n\n    with open('ViewModels/PowerAccentViewModel.cs', encoding='utf-8') as f:\n        lines = f.readlines()\n        for line in lines:\n            if len(line.strip()) < 7 and line.upper() == line:\n                replacements_in_model.append(line)  # 保存需要在模型中替换的内容\n\n    return dict(zip(original_texts, translations)), replacements_in_view, replacements_in_model  # 返回原始文本与翻译的映射，以及需要替换的内容\n\ndef sort_translations(translations):\n    \"\"\"将翻译按照拼音排序\"\"\"\n    sorted_translations = sorted(\n        (pinyin.get(translated_text, format='strip'), original_text)\n        for original_text, translated_text in translations.items()\n    )\n    lst = ['All', 'Currency', 'Pinyin']\n    lst += [original_text for _, original_text in sorted_translations if original_text not in lst]\n    return lst  # 返回排序后的翻译\n\ndef replace_translations_in_file(file_path, original_texts, sorted_translations):\n    \"\"\"在给定文件中替换原始文本为翻译后的文本\"\"\"\n    with open(file_path, encoding='utf-8') as f:\n        content = f.read()  # 读取文件内容\n    temp_replacements = [f'00{i}'[-3:]+'XXXXAUTOTRANSLATIONXXXX' for i in range(len(sorted_translations))]  # 生成临时替换文本\n    for original, temp in zip(original_texts, temp_replacements):\n        content = content.replace(original, temp)  # 将原始文本替换为临时替换文本\n    for temp, sorted_text in zip(temp_replacements, sorted_translations):\n        content = content.replace(temp, sorted_text)  # 将临时替换文本替换为排序后的翻译\n    with open(file_path, 'w', encoding='utf-8') as f:\n        f.write(content)  # 写回文件\n\ndef main():\n    \"\"\"主函数，完成全部工作流程\"\"\"\n    versions = get_power_toys_versions()  # 获取所有版本\n    latest_version = get_latest_version(versions)  # 获取最新版本\n    translations, replacements_in_view, replacements_in_model = get_translations_and_replacements(latest_version)  # 获取翻译和需要替换的内容\n    sorted_translations = sort_translations(translations)  # 将翻译排序\n    for i in sorted_translations:\n        print(f'\\n{i} >>> {translations[i]}')  # 打印排序后的翻译\n    replace_translations_in_file('Views/PowerAccentPage.xaml', replacements_in_view, sorted_translations)  # 在文件中替换翻译\n    replace_translations_in_file('ViewModels/PowerAccentViewModel.cs', replacements_in_model, sorted_translations)  # 在文件中替换翻译\n    print('OK.\\n')\n    input('[按任意键退出...]')  # 等待用户操作后退出\n\nif __name__ == \"__main__\":\n    main()  # 如果是作为脚本运行，调用 main 函数\n"
  },
  {
    "path": "Tools/autosort_old.py",
    "content": "import os\nos.chdir('E:/Translations')\nvers = sorted(i for i in os.listdir() if i.startswith('PowerToys-') and i[-1].isdigit())\nprint(f'发现版本：{\", \".join(vers)}')\ntry:\n    pt = vers[-1]\n    # like 'PowerToys-0.67.0'\n    print(f'选定版本：{pt}')\nexcept:\n    print('无可用版本！')\n    input('[按任意键退出...]')\nprint('\\n确保 Resources.resw 是已翻译的，'\n'将会自动排序修改 PowerAccentPage.xaml 和 PowerAccentViewModel.cs。\\n')\ninput('[按任意键开始]')\n\norig = []\ntrans = []\nreadnextline = False\nos.chdir(pt)\nos.chdir('src/settings-ui/Settings.UI')\n\nwith open('Strings/en-us/Resources.resw', encoding='utf-8') as f:\n    resw = f.readlines()\nfor line in resw:\n    if readnextline:\n        trans.append(line.split('<value>')[-1].split('</value>')[0])\n        readnextline = False\n    if 'QuickAccent_SelectedLanguage_' in line:\n        orig.append(line.split('SelectedLanguage_')[-1].split('.Content')[0])\n        readnextline = True\n\nwith open('Views/PowerAccentPage.xaml', encoding='utf-8') as f:\n    o1 = [l for l in f.readlines() if 'QuickAccent_SelectedLanguage_' in l]\nsort = [l.split('SelectedLanguage_')[-1].split('\"')[0] for l in o1]\nwith open('ViewModels/PowerAccentViewModel.cs', encoding='utf-8') as f:\n    o2 = [l for l in f.readlines() if len(l.strip())<7 and l.upper()==l]\n\nlst = ['All', 'Currency', 'Pinyin']\nso1 = dict(zip(sort, o1))\nso2 = dict(zip(sort, o2))\nst = dict(zip(orig, trans))\nimport pinyin\nx = sorted(zip((pinyin.get(i,format='strip') for i in trans), orig))\nlst += [b for a,b in x if b not in lst]\ns1 = [so1[i] for i in lst]\ns2 = [so2[i] for i in lst]\nran1 = [f'00{i}'[-3:]+'XXXXAUTOTRANSLATIONXXXX' for i in range(len(s1))]\nran2 = [f'00{i}'[-3:]+'XXXXAUTOTRANSLATIONXXXX' for i in range(len(s2))]\n\nfor i in lst:\n    print(f'\\n{i} >>> {st[i]}\\n{so1[i].strip()}\\n{so2[i].strip()}')\n\nwith open('Views/PowerAccentPage.xaml', encoding='utf-8') as f:\n    x1 = f.read()\n    for a,b in zip(o1, ran1):\n        x1 = x1.replace(a, b)\n    for a,b in zip(ran1, s1):\n        x1 = x1.replace(a, b)\nwith open('Views/PowerAccentPage.xaml', mode='w', encoding='utf-8') as f:\n    print('\\nWriting \"Views/PowerAccentPage.xaml\"')\n    f.write(x1)\nwith open('ViewModels/PowerAccentViewModel.cs', encoding='utf-8') as f:\n    x2 = f.read()\n    for a,b in zip(o2, ran2):\n        x2 = x2.replace(a, b)\n    for a,b in zip(ran2, s2):\n        x2 = x2.replace(a, b)\nwith open('ViewModels/PowerAccentViewModel.cs', mode='w', encoding='utf-8') as f:\n    print('Writing \"ViewModels/PowerAccentViewModel.cs\"')\n    f.write(x2)\nprint('OK.\\n')\ninput('[按任意键退出...]')"
  },
  {
    "path": "Tools/blank",
    "content": ""
  },
  {
    "path": "Tools/clean.cmd",
    "content": "@echo off\n:start0\ncd /d %~dp0..\\..\nset pt=%cd%\ncd /d %~dp0\n\nset pt=%pt%\\PowerToys\ntitle PT Source Cleaner - [new: Newest Version] [x / exit: Exit]\necho ɨ赽  ԴĿ¼\nfor /d %%a in (%pt%-*) do set i=%%a&call :finddir\necho.\nset ver=\nset /p ver=汾\ntitle PT Source Cleaner\nif test\"%ver%\"==test\"x\" goto :EOF\nif test\"%ver%\"==test\"exit\" goto :EOF\nif test\"%ver%\"==test\"new\" set ver=%a%\nif test\"%ver%\"==test\"\" cls&goto :start0\n\ncall :title\necho PowerToys Src [%ver%]\n@echo on\n\nrmdir /s /q %pt%-%ver%\\.vs\nrmdir /s /q %pt%-%ver%\\packages\nrmdir /s /q %pt%-%ver%\\x64\nrmdir /s /q %pt%-%ver%\\x86\nrmdir /s /q %pt%-%ver%\\ARM64\nREM rmdir /s /q %pt%-%ver%\\deps\\cxxopts\nrmdir /s /q %pt%-%ver%\\deps\\cziplib\nrmdir /s /q %pt%-%ver%\\deps\\expected-lite\nrmdir /s /q %pt%-%ver%\\deps\\spdlog\nREM mkdir %pt%-%ver%\\deps\\cxxopts\nmkdir %pt%-%ver%\\deps\\cziplib\nmkdir %pt%-%ver%\\deps\\expected-lite\nmkdir %pt%-%ver%\\deps\\spdlog\n\nfor /f \"delims=\" %%a in ('%~dp0bin\\es -path %pt%-%ver% wfn:folder:bin') do rmdir /s /q \"%%a\"\nfor /f \"delims=\" %%a in ('%~dp0bin\\es -path %pt%-%ver% wfn:folder:obj') do rmdir /s /q \"%%a\"\nfor /f \"delims=\" %%a in ('%~dp0bin\\es -path %pt%-%ver% wfn:folder:x64') do rmdir /s /q \"%%a\"\n::for /f \"delims=\" %%a in ('%~dp0bin\\es -path %pt%-%ver% wfn:folder:Win32') do rmdir /s /q \"%%a\"\n:: Plugin's Win32 Folder will be cleaned also!!!\nfor /f \"delims=\" %%a in ('%~dp0bin\\es -path %pt%-%ver% wfn:folder:\"Generated Files\"') do rmdir /s /q \"%%a\"\nfor /f \"delims=\" %%a in ('%~dp0bin\\es -path %pt%-%ver% ext:user') do del /f /q \"%%a\"\n\ndel /f /q \"%pt%-%ver%\\src\\modules\\imageresizer\\dll\\ImageResizerExt_i.c\"\ndel /f /q \"%pt%-%ver%\\src\\modules\\imageresizer\\dll\\ImageResizerExt_i.h\"\ndel /f /q \"%pt%-%ver%\\src\\modules\\imageresizer\\dll\\RCa11568\"\nrmdir /s /q %pt%-%ver%\\src\\modules\\videoconference\\VideoConferenceProxyFilter\\Release\nrmdir /s /q %pt%-%ver%\\src\\modules\\videoconference\\VideoConferenceProxyFilter\\Debug\nrmdir /s /q %pt%-%ver%\\src\\modules\\videoconference\\VideoConferenceShared\\Release\nrmdir /s /q %pt%-%ver%\\src\\modules\\videoconference\\VideoConferenceShared\\Debug\nrmdir /s /q %pt%-%ver%\\src\\common\\version\\Release\nrmdir /s /q %pt%-%ver%\\src\\common\\version\\Debug\n\n@echo off\npause\n:goto :eof\n\n:finddir\necho %i%\nset i=%i:~11%\nif \"%i:~27,1%\"==\"-\" goto :eof\nif \"%i:~27,1%\"==\" \" goto :eof\nREM if \"%i:~-5%\"==\"-orig\" goto :eof\nREM if \"%i:~-9%\"==\"-ORIGINAL\" goto :eof\nREM if \"%i:~-8%\"==\"-fullbak\" goto :eof\nREM if \"%i:~-11%\"==\"-FULLBACKUP\" goto :eof\nREM if \"%i:~-8%\"==\"-FULLBAK\" goto :eof\nREM if \"%i:~-6%\"==\"-patch\" goto :eof\nREM if \"%i:~-6%\"==\"-PATCH\" goto :eof\nset i=%i:~21%\nset a=%i%\necho [NEW] -- %a%\ngoto :EOF\n\n:title\ntitle PT Source Cleaner - %ver%\nif test\"%ver%\"==test\"%a%\" title PT Source Cleaner - %ver% [Newest]\nif not exist \"%pt%-%ver%\" title PT Source Cleaner - %ver% [Not exist!]\ngoto :EOF"
  },
  {
    "path": "Tools/clean.txt",
    "content": "首先 Visual Studio 内项目清理！\n\nDelDeps.cmd :\n\t/.vs\n\t/packages\n\t/x64\n\t/deps/*/*（所有里面的文件夹内的东西，比如cxxopts内的）\n\n*/bin/\n*/obj/\n*/x64/\n*/Generated Files/\n*/*.user\n\n然后用 UltraCompare 扫汉前汉后的文件夹，找漏掉的\n比如：\n[ALWAYS GENERATED FILE] ImageResizerExt_i.c/.h\n\n（其实剩下也没了）\n\n记得安装 everything"
  },
  {
    "path": "Tools/modify.cmd",
    "content": "@echo off\n:start0\ncd /d %~dp0..\nset pt=%cd%\ncd /d %~dp0\n\nset pt=%pt%\\PowerToys\ntitle PT Source Patcher - [new: Newest Version] [x / exit: Exit]\necho ɨ赽  ԴĿ¼\nfor /d %%a in (%pt%-*) do set i=%%a&call :finddir\necho.\nset ver=\nset /p ver=汾\ntitle PT Source Patcher\nif test\"%ver%\"==test\"x\" goto :EOF\nif test\"%ver%\"==test\"exit\" goto :EOF\nif test\"%ver%\"==test\"new\" set ver=%a%\nif test\"%ver%\"==test\"\" cls&goto :start0\n\ncall :title\necho PowerToys Src [%ver%]\n@echo on\n\ncopy /y %pt%-%ver%\\x86\\Release\\modules\\VideoConference\\*_x86* %pt%-%ver%\\x64\\Release\\modules\\VideoConference\\\nmkdir %pt%-%ver%\\x64\\Release\\modules\\launcher\\Plugins\\VSCodeWorkspace\\ 2>nul\ncopy /y %pt%-%ver%\\x64\\Release\\modules\\launcher\\Plugins\\VSCodeWorkspaces %pt%-%ver%\\x64\\Release\\modules\\launcher\\Plugins\\VSCodeWorkspace\\\n\n@echo off\nfor /f \"delims=\" %%a in (zhcn_modify_list.txt) do set zhcn=%%a&call :zhcn\n@echo on\n\n@echo off\nfor /f \"delims=\" %%a in (zhcn_modify_list2.txt) do set zhcn=%%a&call :zhcn2\n@echo on\n\n@echo off\npause\n:goto :eof\n\n:finddir\necho %i%\nset i=%i:~15%\nif \"%i:~-9%\"==\"-ORIGINAL\" goto :eof\nif \"%i:~-5%\"==\"-orig\" goto :eof\nif \"%i:~-6%\"==\"-patch\" goto :eof\nif \"%i:~-4%\"==\"-bak\" goto :eof\nset i=%i:~11%\nset a=%i%\necho [NEW] -- %a%\ngoto :EOF\n\n:title\ntitle PT Source Patcher - %ver%\nif test\"%ver%\"==test\"%a%\" title PT Source Patcher - %ver% [Newest]\nif not exist \"%pt%-%ver%\" title PT Source Patcher - %ver% [Not exist!]\ngoto :EOF\n\n:zhcn\nset zhcn=%pt%-%ver%\\x64\\Release\\%zhcn%\nfor /f \"delims=\" %%a in ('echo %zhcn%') do set zhcnd=%%~dpa&set zhcnn=%%~na&set zhcnx=%%~xa\nmkdir %zhcnd%zh-CN 2>nul\n@echo on\ncopy /y blank %zhcnd%zh-CN\\%zhcnn%.resources%zhcnx%\n@echo off\ngoto :EOF\n\n:zhcn2\nset zhcn=%pt%-%ver%\\x64\\Release\\%zhcn%\nfor /f \"delims=\" %%a in ('echo %zhcn%') do set zhcnd=%%~dpa&set zhcnn=%%~na&set zhcnx=%%~xa\nmkdir %zhcnd%zh-CN 2>nul\n@echo on\ncopy /y %zhcnn%.resources%zhcnx% %zhcnd%zh-CN\\%zhcnn%.resources%zhcnx%\n@echo off\ngoto :EOF"
  },
  {
    "path": "Tools/modify_arm64.cmd",
    "content": "@echo off\n:start0\ncd /d %~dp0..\nset pt=%cd%\ncd /d %~dp0\n\nset pt=%pt%\\PowerToys\ntitle PT Source Patcher - [new: Newest Version] [x / exit: Exit]\necho ɨ赽  ԴĿ¼\nfor /d %%a in (%pt%-*) do set i=%%a&call :finddir\necho.\nset ver=\nset /p ver=汾\ntitle PT Source Patcher\nif test\"%ver%\"==test\"x\" goto :EOF\nif test\"%ver%\"==test\"exit\" goto :EOF\nif test\"%ver%\"==test\"new\" set ver=%a%\nif test\"%ver%\"==test\"\" cls&goto :start0\n\ncall :title\necho PowerToys Src [%ver%]\n@echo on\n\nmkdir %pt%-%ver%\\ARM64\\Release\\modules\\launcher\\Plugins\\VSCodeWorkspace\\ 2>nul\ncopy /y %pt%-%ver%\\ARM64\\Release\\modules\\launcher\\Plugins\\VSCodeWorkspaces %pt%-%ver%\\ARM64\\Release\\modules\\launcher\\Plugins\\VSCodeWorkspace\\\n\n@echo off\nfor /f \"delims=\" %%a in (zhcn_modify_list.txt) do set zhcn=%%a&call :zhcn\n@echo on\n\n@echo off\nfor /f \"delims=\" %%a in (zhcn_modify_list2.txt) do set zhcn=%%a&call :zhcn2\n@echo on\n\n@echo off\npause\n:goto :eof\n\n:finddir\necho %i%\nset i=%i:~15%\nif \"%i:~-9%\"==\"-ORIGINAL\" goto :eof\nif \"%i:~-5%\"==\"-orig\" goto :eof\nif \"%i:~-6%\"==\"-patch\" goto :eof\nif \"%i:~-4%\"==\"-bak\" goto :eof\nset i=%i:~11%\nset a=%i%\necho [NEW] -- %a%\ngoto :EOF\n\n:title\ntitle PT Source Patcher - %ver%\nif test\"%ver%\"==test\"%a%\" title PT Source Patcher - %ver% [Newest]\nif not exist \"%pt%-%ver%\" title PT Source Patcher - %ver% [Not exist!]\ngoto :EOF\n\n:zhcn\nset zhcn=%pt%-%ver%\\ARM64\\Release\\%zhcn%\nfor /f \"delims=\" %%a in ('echo %zhcn%') do set zhcnd=%%~dpa&set zhcnn=%%~na&set zhcnx=%%~xa\nmkdir %zhcnd%zh-CN 2>nul\n@echo on\ncopy /y blank %zhcnd%zh-CN\\%zhcnn%.resources%zhcnx%\n@echo off\ngoto :EOF\n\n:zhcn2\nset zhcn=%pt%-%ver%\\ARM64\\Release\\%zhcn%\nfor /f \"delims=\" %%a in ('echo %zhcn%') do set zhcnd=%%~dpa&set zhcnn=%%~na&set zhcnx=%%~xa\nmkdir %zhcnd%zh-CN 2>nul\n@echo on\ncopy /y %zhcnn%.resources%zhcnx% %zhcnd%zh-CN\\%zhcnn%.resources%zhcnx%\n@echo off\ngoto :EOF"
  },
  {
    "path": "Tools/zhcn_modify_list.txt",
    "content": "modules\\launcher\\Plugins\\UnitConverter\\Community.PowerToys.Run.Plugin.UnitConverter.dll\nmodules\\launcher\\Plugins\\VSCodeWorkspace\\Community.PowerToys.Run.Plugin.VSCodeWorkspaces.dll\nmodules\\launcher\\Plugins\\WebSearch\\Community.PowerToys.Run.Plugin.WebSearch.dll\nmodules\\launcher\\Plugins\\Folder\\Microsoft.Plugin.Folder.dll\nmodules\\launcher\\Plugins\\Indexer\\Microsoft.Plugin.Indexer.dll\nmodules\\launcher\\Plugins\\Program\\Microsoft.Plugin.Program.dll\nmodules\\launcher\\Plugins\\Shell\\Microsoft.Plugin.Shell.dll\nmodules\\launcher\\Plugins\\Uri\\Microsoft.Plugin.Uri.dll\nmodules\\launcher\\Plugins\\WindowWalker\\Microsoft.Plugin.WindowWalker.dll\nmodules\\launcher\\Plugins\\Calculator\\Microsoft.PowerToys.Run.Plugin.Calculator.dll\nmodules\\launcher\\Plugins\\Registry\\Microsoft.PowerToys.Run.Plugin.Registry.dll\nmodules\\launcher\\Plugins\\Service\\Microsoft.PowerToys.Run.Plugin.Service.dll\nmodules\\launcher\\Plugins\\System\\Microsoft.PowerToys.Run.Plugin.System.dll\nmodules\\launcher\\Plugins\\TimeDate\\Microsoft.PowerToys.Run.Plugin.TimeDate.dll\nmodules\\launcher\\Plugins\\WindowsSettings\\Microsoft.PowerToys.Run.Plugin.WindowsSettings.dll\nmodules\\launcher\\Plugins\\WindowsTerminal\\Microsoft.PowerToys.Run.Plugin.WindowsTerminal.dll\nmodules\\ColorPicker\\PowerToys.ColorPickerUI.dll\nmodules\\FancyZones\\PowerToys.FancyZonesEditor.dll\nmodules\\FileExplorerPreview\\PowerToys.GcodePreviewHandler.dll\nmodules\\ImageResizer\\PowerToys.ImageResizer.dll\nmodules\\FileExplorerPreview\\PowerToys.MarkdownPreviewHandler.dll\nmodules\\FileExplorerPreview\\PowerToys.MonacoPreviewHandler.dll\nmodules\\FileExplorerPreview\\PowerToys.PdfPreviewHandler.dll\nmodules\\launcher\\PowerToys.PowerLauncher.dll\nmodules\\FileExplorerPreview\\PowerToys.SvgPreviewHandler.dll"
  },
  {
    "path": "Tools/zhcn_modify_list2.txt",
    "content": ""
  },
  {
    "path": "Tools/zhcn_modify_list2.txt.bak",
    "content": "modules\\ColorPicker\\ModernWpf.Controls.dll\nmodules\\FancyZones\\ModernWpf.Controls.dll\nmodules\\ImageResizer\\ModernWpf.Controls.dll\nmodules\\launcher\\ModernWpf.Controls.dll\nmodules\\ColorPicker\\ModernWpf.dll\nmodules\\FancyZones\\ModernWpf.dll\nmodules\\ImageResizer\\ModernWpf.dll\nmodules\\launcher\\ModernWpf.dll"
  }
]