[
  {
    "path": ".github/ISSUE_TEMPLATE/01_bug_report.yml",
    "content": "name: Bug 报告\ndescription: 在提出问题前请先自行排除服务器端问题和升级到最新客户端，同时也请通过搜索确认是否有人提出过相同问题。\ntitle: \"[Bug]: \"\nlabels: [\"bug\"]\nbody:\n  - type: input\n    id: \"expectation\"\n    attributes:\n      label: \"预期情况\"\n      description: \"描述你认为应该发生什么\"\n    validations:\n      required: true\n  - type: textarea\n    id: \"describe-the-bug\"\n    attributes:\n      label: \"实际情况\"\n      description: \"描述实际发生了什么\"\n    validations:\n      required: true\n  - type: textarea\n    id: \"reproduction-method\"\n    attributes:\n      label: \"复现方法\"\n      description: \"在BUG出现前执行了哪些操作\"\n      placeholder: 标序号\n    validations:\n      required: true\n  - type: textarea\n    id: \"log\"\n    attributes:\n      label: \"日志信息\"\n      description: \"位置在软件当前目录下的guiLogs\"\n      placeholder: 在日志开始和结束位置粘贴冒号后的内容：```\n    validations:\n      required: true\n  - type: textarea\n    id: \"more\"\n    attributes:\n      label: \"额外信息\"\n      description: \"可选\"\n    validations:\n      required: false\n  - type: checkboxes\n    id: \"latest-version\"\n    attributes:\n      label: \"我确认已更新至最新版本\"\n      description: \"否则请更新后尝试\"\n      options:\n        - label: 是\n          required: true\n  - type: checkboxes\n    id: \"issues\"\n    attributes:\n      label: \"我确认已查询历史issues\"\n      description: \"否则请查询后提出\"\n      options:\n        - label: 是\n          required: true\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/02_feature_request.yml",
    "content": "name: Feature 请求\ndescription: \"为这个项目提出一个建议\"\ntitle: \"[Feature request]: \"\nlabels: ['enhancement']\nbody: \n- type: input\n  id: problem\n  attributes:\n    label: 相关问题\n    description: \"清楚而简洁地描述问题是什么。\"\n    placeholder: \"当我想要……时，软件不能……\"\n  validations:\n    required: true\n- type: input\n  id: way-to-solve\n  attributes:\n    label: 描述你希望的解决方案\n    description: \"你希望发生什么\"\n  validations:\n    required: true\n- type: input\n  id: instead\n  attributes:\n    label: 描述你所考虑的替代方案\n  validations:\n    required: false\n- type: checkboxes\n  id: \"issues\"\n  attributes:\n    label: \"我确认已查询历史issues\"\n    description: \"否则请查询后提出\"\n    options:\n      - label: 是\n        required: true\n"
  },
  {
    "path": ".github/workflows/ci.yml",
    "content": "# This workflow uses actions that are not certified by GitHub.\n# They are provided by a third-party and are governed by\n# separate terms of service, privacy policy, and support\n# documentation.\n\n# This workflow will build, test, sign and package a WPF or Windows Forms desktop application\n# built on .NET Core.\n# To learn how to migrate your existing application to .NET Core,\n# refer to https://docs.microsoft.com/en-us/dotnet/desktop-wpf/migration/convert-project-from-net-framework\n#\n# To configure this workflow:\n#\n# 1. Configure environment variables\n# GitHub sets default environment variables for every workflow run.\n# Replace the variables relative to your project in the \"env\" section below.\n#\n# 2. Signing\n# Generate a signing certificate in the Windows Application\n# Packaging Project or add an existing signing certificate to the project.\n# Next, use PowerShell to encode the .pfx file using Base64 encoding\n# by running the following Powershell script to generate the output string:\n#\n# $pfx_cert = Get-Content '.\\SigningCertificate.pfx' -Encoding Byte\n# [System.Convert]::ToBase64String($pfx_cert) | Out-File 'SigningCertificate_Encoded.txt'\n#\n# Open the output file, SigningCertificate_Encoded.txt, and copy the\n# string inside. Then, add the string to the repo as a GitHub secret\n# and name it \"Base64_Encoded_Pfx.\"\n# For more information on how to configure your signing certificate for\n# this workflow, refer to https://github.com/microsoft/github-actions-for-desktop-apps#signing\n#\n# Finally, add the signing certificate password to the repo as a secret and name it \"Pfx_Key\".\n# See \"Build the Windows Application Packaging project\" below to see how the secret is used.\n#\n# For more information on GitHub Actions, refer to https://github.com/features/actions\n# For a complete CI/CD sample to get started with GitHub Action workflows for Desktop Applications,\n# refer to https://github.com/microsoft/github-actions-for-desktop-apps\n\nname: .NET Core Desktop\n\non:\n  push:\n    branches: [ \"master\" ]\n  pull_request:\n    branches: [ \"master\" ]\n\njobs:\n\n  build:\n\n    strategy:\n      matrix:\n          include:\n          - configuration: x64\n            xray: Xray-windows-64.zip\n          - configuration: x86\n            xray: Xray-windows-32.zip\n      \n\n    runs-on: windows-latest  # For a list of available runner types, refer to\n                             # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on\n\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v3\n      with:\n        fetch-depth: 0\n    - name: Download xray\n      run: |\n        curl -L -o ${{ matrix.xray }} https://github.com/hiddify/Hiddify-Xray-core/releases/latest/download/${{ matrix.xray }}\n        dir\n      \n    \n\n    # Install the .NET Core workload\n    - name: Install .NET Core\n      uses: actions/setup-dotnet@v3\n      with:\n        dotnet-version: 6.0.x\n    - name: Restore\n      run: | \n        dotnet restore\n      working-directory: v2rayN\n        \n    \n    - name: Build\n      working-directory: v2rayN\n      run: |\n        dotnet build --configuration Release --no-restore\n        \n    - name: Publish win ${{ matrix.configuration }}\n      working-directory: v2rayN\n      run: |\n        dotnet publish v2rayN\\v2rayN.csproj --property WarningLevel=0 -c Release -o ../release/win-${{ matrix.configuration }} -r win-${{ matrix.configuration }} -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true /p:PublishSingleFileExecutable=HiddifyN.exe\n#        dotnet publish --property WarningLevel=0 -c Release -o ../release/win-x64 -r win-x64 -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true          \n    - name: add xray\n      run: |\n        mkdir release\\win-${{ matrix.configuration }}\\bin\\Xray\n        dir\n        7z x \"${{ matrix.xray }}\" -i!\"*.exe\"\n        move *xray.exe  release\\win-${{ matrix.configuration }}\\bin\\Xray\\\n        \n    # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact\n    - name: Upload build win-${{ matrix.configuration }}\n      uses: actions/upload-artifact@v3\n      with:\n        name: win-${{ matrix.configuration }}\n        path: release/win-${{ matrix.configuration }}\n        retention-days: 5\n\n    \n"
  },
  {
    "path": ".github/workflows/release.yml",
    "content": "name: Release\non:\n  push:\n    # Sequence of patterns matched against refs/tags\n    tags:\n      - \"v*\"\n\njobs:\n\n  build:\n\n    strategy:\n      matrix:\n          include:\n          - configuration: x64\n            xray: Xray-windows-64.zip\n          - configuration: x86\n            xray: Xray-windows-32.zip\n      \n\n    runs-on: windows-latest  # For a list of available runner types, refer to\n                             # https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idruns-on\n\n    steps:\n    - name: Checkout\n      uses: actions/checkout@v3\n      with:\n        fetch-depth: 0\n    - name: Download xray\n      run: |\n        curl -L -o ${{ matrix.xray }} https://github.com/hiddify/Hiddify-Xray-core/releases/latest/download/${{ matrix.xray }}\n        dir\n      \n    \n\n    # Install the .NET Core workload\n    - name: Install .NET Core\n      uses: actions/setup-dotnet@v3\n      with:\n        dotnet-version: 6.0.x\n    - name: Restore\n      run: | \n        dotnet restore\n      working-directory: v2rayN\n        \n    \n    - name: Build\n      working-directory: v2rayN\n      run: |\n        dotnet build --configuration Release --no-restore\n        \n    - name: Publish win ${{ matrix.configuration }}\n      working-directory: v2rayN\n      run: |\n        dotnet publish v2rayN\\v2rayN.csproj --property WarningLevel=0 -c Release -o ../release/win-${{ matrix.configuration }} -r win-${{ matrix.configuration }} -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true /p:PublishSingleFileExecutable=HiddifyN.exe\n#        dotnet publish --property WarningLevel=0 -c Release -o ../release/win-x64 -r win-x64 -p:PublishSingleFile=true --self-contained false /p:UseAppHost=true /p:PublishReadyToRun=true          \n    - name: add xray\n      run: |\n        mkdir release\\win-${{ matrix.configuration }}\\bin\\Xray\n        dir\n        7z x \"${{ matrix.xray }}\" -i!\"*.exe\"\n        move *xray.exe  release\\win-${{ matrix.configuration }}\\bin\\Xray\\\n        \n    # Upload the MSIX package: https://github.com/marketplace/actions/upload-a-build-artifact\n    - name: Upload build win-${{ matrix.configuration }}\n      uses: actions/upload-artifact@v3\n      with:\n        name: win-${{ matrix.configuration }}\n        path: release/win-${{ matrix.configuration }}\n        retention-days: 5\n  publish:\n    runs-on: ubuntu-latest\n    steps:\n    - uses: actions/checkout@v1\n    - name: Load Release URL File from release job\n      uses: actions/download-artifact@v1\n      with:\n        name: win-x64.zip\n    - name: Load Release URL File from release job\n      uses: actions/download-artifact@v1\n      with:\n        name: win-x86.zip\n    - name: Upload Release\n      uses: softprops/action-gh-release@v1\n      with:\n          # tag: ${{ github.ref_name }}\n          tag_name: ${{ github.ref }}\n          release_name: ${{ github.ref }}\n          files: \"*.zip\"\n          prerelease: false\n          generate_release_notes: true    \n"
  },
  {
    "path": ".gitignore",
    "content": "﻿################################################################################\n# 此 .gitignore 文件已由 Microsoft(R) Visual Studio 自动创建。\n################################################################################\n\n/vs\n/v2rayN/.vs/\n/v2rayN/v2rayN/bin/Debug/app.publish\n/v2rayN/v2rayN/bin/Debug\n/v2rayN/v2rayN/bin/Release\n/v2rayN/v2rayN/obj/\n/v2rayN/.vs/v2rayN/DesignTimeBuild\n/v2rayN/packages\n.vs/ProjectSettings.json\n.vs/slnx.sqlite\n.vs/VSWorkspaceState.json\n/v2rayN/v2rayUpgrade/bin/Debug\n/v2rayN/v2rayUpgrade/bin/Release\n/v2rayN/v2rayUpgrade/obj/\n*.user\n/v2rayN/v2rayN/Properties/*\n/v2rayN/v2rayN/Properties/\n/.vs/v2rayN"
  },
  {
    "path": "LICENSE",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 3, 29 June 2007\n\n Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The GNU General Public License is a free, copyleft license for\nsoftware and other kinds of works.\n\n  The licenses for most software and other practical works are designed\nto take away your freedom to share and change the works.  By contrast,\nthe GNU General Public License is intended to guarantee your freedom to\nshare and change all versions of a program--to make sure it remains free\nsoftware for all its users.  We, the Free Software Foundation, use the\nGNU General Public License for most of our software; it applies also to\nany other work released this way by its authors.  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthem if you wish), that you receive source code or can get it if you\nwant it, that you can change the software or use pieces of it in new\nfree programs, and that you know you can do these things.\n\n  To protect your rights, we need to prevent others from denying you\nthese rights or asking you to surrender the rights.  Therefore, you have\ncertain responsibilities if you distribute copies of the software, or if\nyou modify it: responsibilities to respect the freedom of others.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must pass on to the recipients the same\nfreedoms that you received.  You must make sure that they, too, receive\nor can get the source code.  And you must show them these terms so they\nknow their rights.\n\n  Developers that use the GNU GPL protect your rights with two steps:\n(1) assert copyright on the software, and (2) offer you this License\ngiving you legal permission to copy, distribute and/or modify it.\n\n  For the developers' and authors' protection, the GPL clearly explains\nthat there is no warranty for this free software.  For both users' and\nauthors' sake, the GPL requires that modified versions be marked as\nchanged, so that their problems will not be attributed erroneously to\nauthors of previous versions.\n\n  Some devices are designed to deny users access to install or run\nmodified versions of the software inside them, although the manufacturer\ncan do so.  This is fundamentally incompatible with the aim of\nprotecting users' freedom to change the software.  The systematic\npattern of such abuse occurs in the area of products for individuals to\nuse, which is precisely where it is most unacceptable.  Therefore, we\nhave designed this version of the GPL to prohibit the practice for those\nproducts.  If such problems arise substantially in other domains, we\nstand ready to extend this provision to those domains in future versions\nof the GPL, as needed to protect the freedom of users.\n\n  Finally, every program is threatened constantly by software patents.\nStates should not allow patents to restrict development and use of\nsoftware on general-purpose computers, but in those that do, we wish to\navoid the special danger that patents applied to a free program could\nmake it effectively proprietary.  To prevent this, the GPL assures that\npatents cannot be used to render the program non-free.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                       TERMS AND CONDITIONS\n\n  0. Definitions.\n\n  \"This License\" refers to version 3 of the GNU General Public License.\n\n  \"Copyright\" also means copyright-like laws that apply to other kinds of\nworks, such as semiconductor masks.\n\n  \"The Program\" refers to any copyrightable work licensed under this\nLicense.  Each licensee is addressed as \"you\".  \"Licensees\" and\n\"recipients\" may be individuals or organizations.\n\n  To \"modify\" a work means to copy from or adapt all or part of the work\nin a fashion requiring copyright permission, other than the making of an\nexact copy.  The resulting work is called a \"modified version\" of the\nearlier work or a work \"based on\" the earlier work.\n\n  A \"covered work\" means either the unmodified Program or a work based\non the Program.\n\n  To \"propagate\" a work means to do anything with it that, without\npermission, would make you directly or secondarily liable for\ninfringement under applicable copyright law, except executing it on a\ncomputer or modifying a private copy.  Propagation includes copying,\ndistribution (with or without modification), making available to the\npublic, and in some countries other activities as well.\n\n  To \"convey\" a work means any kind of propagation that enables other\nparties to make or receive copies.  Mere interaction with a user through\na computer network, with no transfer of a copy, is not conveying.\n\n  An interactive user interface displays \"Appropriate Legal Notices\"\nto the extent that it includes a convenient and prominently visible\nfeature that (1) displays an appropriate copyright notice, and (2)\ntells the user that there is no warranty for the work (except to the\nextent that warranties are provided), that licensees may convey the\nwork under this License, and how to view a copy of this License.  If\nthe interface presents a list of user commands or options, such as a\nmenu, a prominent item in the list meets this criterion.\n\n  1. Source Code.\n\n  The \"source code\" for a work means the preferred form of the work\nfor making modifications to it.  \"Object code\" means any non-source\nform of a work.\n\n  A \"Standard Interface\" means an interface that either is an official\nstandard defined by a recognized standards body, or, in the case of\ninterfaces specified for a particular programming language, one that\nis widely used among developers working in that language.\n\n  The \"System Libraries\" of an executable work include anything, other\nthan the work as a whole, that (a) is included in the normal form of\npackaging a Major Component, but which is not part of that Major\nComponent, and (b) serves only to enable use of the work with that\nMajor Component, or to implement a Standard Interface for which an\nimplementation is available to the public in source code form.  A\n\"Major Component\", in this context, means a major essential component\n(kernel, window system, and so on) of the specific operating system\n(if any) on which the executable work runs, or a compiler used to\nproduce the work, or an object code interpreter used to run it.\n\n  The \"Corresponding Source\" for a work in object code form means all\nthe source code needed to generate, install, and (for an executable\nwork) run the object code and to modify the work, including scripts to\ncontrol those activities.  However, it does not include the work's\nSystem Libraries, or general-purpose tools or generally available free\nprograms which are used unmodified in performing those activities but\nwhich are not part of the work.  For example, Corresponding Source\nincludes interface definition files associated with source files for\nthe work, and the source code for shared libraries and dynamically\nlinked subprograms that the work is specifically designed to require,\nsuch as by intimate data communication or control flow between those\nsubprograms and other parts of the work.\n\n  The Corresponding Source need not include anything that users\ncan regenerate automatically from other parts of the Corresponding\nSource.\n\n  The Corresponding Source for a work in source code form is that\nsame work.\n\n  2. Basic Permissions.\n\n  All rights granted under this License are granted for the term of\ncopyright on the Program, and are irrevocable provided the stated\nconditions are met.  This License explicitly affirms your unlimited\npermission to run the unmodified Program.  The output from running a\ncovered work is covered by this License only if the output, given its\ncontent, constitutes a covered work.  This License acknowledges your\nrights of fair use or other equivalent, as provided by copyright law.\n\n  You may make, run and propagate covered works that you do not\nconvey, without conditions so long as your license otherwise remains\nin force.  You may convey covered works to others for the sole purpose\nof having them make modifications exclusively for you, or provide you\nwith facilities for running those works, provided that you comply with\nthe terms of this License in conveying all material for which you do\nnot control copyright.  Those thus making or running the covered works\nfor you must do so exclusively on your behalf, under your direction\nand control, on terms that prohibit them from making any copies of\nyour copyrighted material outside their relationship with you.\n\n  Conveying under any other circumstances is permitted solely under\nthe conditions stated below.  Sublicensing is not allowed; section 10\nmakes it unnecessary.\n\n  3. Protecting Users' Legal Rights From Anti-Circumvention Law.\n\n  No covered work shall be deemed part of an effective technological\nmeasure under any applicable law fulfilling obligations under article\n11 of the WIPO copyright treaty adopted on 20 December 1996, or\nsimilar laws prohibiting or restricting circumvention of such\nmeasures.\n\n  When you convey a covered work, you waive any legal power to forbid\ncircumvention of technological measures to the extent such circumvention\nis effected by exercising rights under this License with respect to\nthe covered work, and you disclaim any intention to limit operation or\nmodification of the work as a means of enforcing, against the work's\nusers, your or third parties' legal rights to forbid circumvention of\ntechnological measures.\n\n  4. Conveying Verbatim Copies.\n\n  You may convey verbatim copies of the Program's source code as you\nreceive it, in any medium, provided that you conspicuously and\nappropriately publish on each copy an appropriate copyright notice;\nkeep intact all notices stating that this License and any\nnon-permissive terms added in accord with section 7 apply to the code;\nkeep intact all notices of the absence of any warranty; and give all\nrecipients a copy of this License along with the Program.\n\n  You may charge any price or no price for each copy that you convey,\nand you may offer support or warranty protection for a fee.\n\n  5. Conveying Modified Source Versions.\n\n  You may convey a work based on the Program, or the modifications to\nproduce it from the Program, in the form of source code under the\nterms of section 4, provided that you also meet all of these conditions:\n\n    a) The work must carry prominent notices stating that you modified\n    it, and giving a relevant date.\n\n    b) The work must carry prominent notices stating that it is\n    released under this License and any conditions added under section\n    7.  This requirement modifies the requirement in section 4 to\n    \"keep intact all notices\".\n\n    c) You must license the entire work, as a whole, under this\n    License to anyone who comes into possession of a copy.  This\n    License will therefore apply, along with any applicable section 7\n    additional terms, to the whole of the work, and all its parts,\n    regardless of how they are packaged.  This License gives no\n    permission to license the work in any other way, but it does not\n    invalidate such permission if you have separately received it.\n\n    d) If the work has interactive user interfaces, each must display\n    Appropriate Legal Notices; however, if the Program has interactive\n    interfaces that do not display Appropriate Legal Notices, your\n    work need not make them do so.\n\n  A compilation of a covered work with other separate and independent\nworks, which are not by their nature extensions of the covered work,\nand which are not combined with it such as to form a larger program,\nin or on a volume of a storage or distribution medium, is called an\n\"aggregate\" if the compilation and its resulting copyright are not\nused to limit the access or legal rights of the compilation's users\nbeyond what the individual works permit.  Inclusion of a covered work\nin an aggregate does not cause this License to apply to the other\nparts of the aggregate.\n\n  6. Conveying Non-Source Forms.\n\n  You may convey a covered work in object code form under the terms\nof sections 4 and 5, provided that you also convey the\nmachine-readable Corresponding Source under the terms of this License,\nin one of these ways:\n\n    a) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by the\n    Corresponding Source fixed on a durable physical medium\n    customarily used for software interchange.\n\n    b) Convey the object code in, or embodied in, a physical product\n    (including a physical distribution medium), accompanied by a\n    written offer, valid for at least three years and valid for as\n    long as you offer spare parts or customer support for that product\n    model, to give anyone who possesses the object code either (1) a\n    copy of the Corresponding Source for all the software in the\n    product that is covered by this License, on a durable physical\n    medium customarily used for software interchange, for a price no\n    more than your reasonable cost of physically performing this\n    conveying of source, or (2) access to copy the\n    Corresponding Source from a network server at no charge.\n\n    c) Convey individual copies of the object code with a copy of the\n    written offer to provide the Corresponding Source.  This\n    alternative is allowed only occasionally and noncommercially, and\n    only if you received the object code with such an offer, in accord\n    with subsection 6b.\n\n    d) Convey the object code by offering access from a designated\n    place (gratis or for a charge), and offer equivalent access to the\n    Corresponding Source in the same way through the same place at no\n    further charge.  You need not require recipients to copy the\n    Corresponding Source along with the object code.  If the place to\n    copy the object code is a network server, the Corresponding Source\n    may be on a different server (operated by you or a third party)\n    that supports equivalent copying facilities, provided you maintain\n    clear directions next to the object code saying where to find the\n    Corresponding Source.  Regardless of what server hosts the\n    Corresponding Source, you remain obligated to ensure that it is\n    available for as long as needed to satisfy these requirements.\n\n    e) Convey the object code using peer-to-peer transmission, provided\n    you inform other peers where the object code and Corresponding\n    Source of the work are being offered to the general public at no\n    charge under subsection 6d.\n\n  A separable portion of the object code, whose source code is excluded\nfrom the Corresponding Source as a System Library, need not be\nincluded in conveying the object code work.\n\n  A \"User Product\" is either (1) a \"consumer product\", which means any\ntangible personal property which is normally used for personal, family,\nor household purposes, or (2) anything designed or sold for incorporation\ninto a dwelling.  In determining whether a product is a consumer product,\ndoubtful cases shall be resolved in favor of coverage.  For a particular\nproduct received by a particular user, \"normally used\" refers to a\ntypical or common use of that class of product, regardless of the status\nof the particular user or of the way in which the particular user\nactually uses, or expects or is expected to use, the product.  A product\nis a consumer product regardless of whether the product has substantial\ncommercial, industrial or non-consumer uses, unless such uses represent\nthe only significant mode of use of the product.\n\n  \"Installation Information\" for a User Product means any methods,\nprocedures, authorization keys, or other information required to install\nand execute modified versions of a covered work in that User Product from\na modified version of its Corresponding Source.  The information must\nsuffice to ensure that the continued functioning of the modified object\ncode is in no case prevented or interfered with solely because\nmodification has been made.\n\n  If you convey an object code work under this section in, or with, or\nspecifically for use in, a User Product, and the conveying occurs as\npart of a transaction in which the right of possession and use of the\nUser Product is transferred to the recipient in perpetuity or for a\nfixed term (regardless of how the transaction is characterized), the\nCorresponding Source conveyed under this section must be accompanied\nby the Installation Information.  But this requirement does not apply\nif neither you nor any third party retains the ability to install\nmodified object code on the User Product (for example, the work has\nbeen installed in ROM).\n\n  The requirement to provide Installation Information does not include a\nrequirement to continue to provide support service, warranty, or updates\nfor a work that has been modified or installed by the recipient, or for\nthe User Product in which it has been modified or installed.  Access to a\nnetwork may be denied when the modification itself materially and\nadversely affects the operation of the network or violates the rules and\nprotocols for communication across the network.\n\n  Corresponding Source conveyed, and Installation Information provided,\nin accord with this section must be in a format that is publicly\ndocumented (and with an implementation available to the public in\nsource code form), and must require no special password or key for\nunpacking, reading or copying.\n\n  7. Additional Terms.\n\n  \"Additional permissions\" are terms that supplement the terms of this\nLicense by making exceptions from one or more of its conditions.\nAdditional permissions that are applicable to the entire Program shall\nbe treated as though they were included in this License, to the extent\nthat they are valid under applicable law.  If additional permissions\napply only to part of the Program, that part may be used separately\nunder those permissions, but the entire Program remains governed by\nthis License without regard to the additional permissions.\n\n  When you convey a copy of a covered work, you may at your option\nremove any additional permissions from that copy, or from any part of\nit.  (Additional permissions may be written to require their own\nremoval in certain cases when you modify the work.)  You may place\nadditional permissions on material, added by you to a covered work,\nfor which you have or can give appropriate copyright permission.\n\n  Notwithstanding any other provision of this License, for material you\nadd to a covered work, you may (if authorized by the copyright holders of\nthat material) supplement the terms of this License with terms:\n\n    a) Disclaiming warranty or limiting liability differently from the\n    terms of sections 15 and 16 of this License; or\n\n    b) Requiring preservation of specified reasonable legal notices or\n    author attributions in that material or in the Appropriate Legal\n    Notices displayed by works containing it; or\n\n    c) Prohibiting misrepresentation of the origin of that material, or\n    requiring that modified versions of such material be marked in\n    reasonable ways as different from the original version; or\n\n    d) Limiting the use for publicity purposes of names of licensors or\n    authors of the material; or\n\n    e) Declining to grant rights under trademark law for use of some\n    trade names, trademarks, or service marks; or\n\n    f) Requiring indemnification of licensors and authors of that\n    material by anyone who conveys the material (or modified versions of\n    it) with contractual assumptions of liability to the recipient, for\n    any liability that these contractual assumptions directly impose on\n    those licensors and authors.\n\n  All other non-permissive additional terms are considered \"further\nrestrictions\" within the meaning of section 10.  If the Program as you\nreceived it, or any part of it, contains a notice stating that it is\ngoverned by this License along with a term that is a further\nrestriction, you may remove that term.  If a license document contains\na further restriction but permits relicensing or conveying under this\nLicense, you may add to a covered work material governed by the terms\nof that license document, provided that the further restriction does\nnot survive such relicensing or conveying.\n\n  If you add terms to a covered work in accord with this section, you\nmust place, in the relevant source files, a statement of the\nadditional terms that apply to those files, or a notice indicating\nwhere to find the applicable terms.\n\n  Additional terms, permissive or non-permissive, may be stated in the\nform of a separately written license, or stated as exceptions;\nthe above requirements apply either way.\n\n  8. Termination.\n\n  You may not propagate or modify a covered work except as expressly\nprovided under this License.  Any attempt otherwise to propagate or\nmodify it is void, and will automatically terminate your rights under\nthis License (including any patent licenses granted under the third\nparagraph of section 11).\n\n  However, if you cease all violation of this License, then your\nlicense from a particular copyright holder is reinstated (a)\nprovisionally, unless and until the copyright holder explicitly and\nfinally terminates your license, and (b) permanently, if the copyright\nholder fails to notify you of the violation by some reasonable means\nprior to 60 days after the cessation.\n\n  Moreover, your license from a particular copyright holder is\nreinstated permanently if the copyright holder notifies you of the\nviolation by some reasonable means, this is the first time you have\nreceived notice of violation of this License (for any work) from that\ncopyright holder, and you cure the violation prior to 30 days after\nyour receipt of the notice.\n\n  Termination of your rights under this section does not terminate the\nlicenses of parties who have received copies or rights from you under\nthis License.  If your rights have been terminated and not permanently\nreinstated, you do not qualify to receive new licenses for the same\nmaterial under section 10.\n\n  9. Acceptance Not Required for Having Copies.\n\n  You are not required to accept this License in order to receive or\nrun a copy of the Program.  Ancillary propagation of a covered work\noccurring solely as a consequence of using peer-to-peer transmission\nto receive a copy likewise does not require acceptance.  However,\nnothing other than this License grants you permission to propagate or\nmodify any covered work.  These actions infringe copyright if you do\nnot accept this License.  Therefore, by modifying or propagating a\ncovered work, you indicate your acceptance of this License to do so.\n\n  10. Automatic Licensing of Downstream Recipients.\n\n  Each time you convey a covered work, the recipient automatically\nreceives a license from the original licensors, to run, modify and\npropagate that work, subject to this License.  You are not responsible\nfor enforcing compliance by third parties with this License.\n\n  An \"entity transaction\" is a transaction transferring control of an\norganization, or substantially all assets of one, or subdividing an\norganization, or merging organizations.  If propagation of a covered\nwork results from an entity transaction, each party to that\ntransaction who receives a copy of the work also receives whatever\nlicenses to the work the party's predecessor in interest had or could\ngive under the previous paragraph, plus a right to possession of the\nCorresponding Source of the work from the predecessor in interest, if\nthe predecessor has it or can get it with reasonable efforts.\n\n  You may not impose any further restrictions on the exercise of the\nrights granted or affirmed under this License.  For example, you may\nnot impose a license fee, royalty, or other charge for exercise of\nrights granted under this License, and you may not initiate litigation\n(including a cross-claim or counterclaim in a lawsuit) alleging that\nany patent claim is infringed by making, using, selling, offering for\nsale, or importing the Program or any portion of it.\n\n  11. Patents.\n\n  A \"contributor\" is a copyright holder who authorizes use under this\nLicense of the Program or a work on which the Program is based.  The\nwork thus licensed is called the contributor's \"contributor version\".\n\n  A contributor's \"essential patent claims\" are all patent claims\nowned or controlled by the contributor, whether already acquired or\nhereafter acquired, that would be infringed by some manner, permitted\nby this License, of making, using, or selling its contributor version,\nbut do not include claims that would be infringed only as a\nconsequence of further modification of the contributor version.  For\npurposes of this definition, \"control\" includes the right to grant\npatent sublicenses in a manner consistent with the requirements of\nthis License.\n\n  Each contributor grants you a non-exclusive, worldwide, royalty-free\npatent license under the contributor's essential patent claims, to\nmake, use, sell, offer for sale, import and otherwise run, modify and\npropagate the contents of its contributor version.\n\n  In the following three paragraphs, a \"patent license\" is any express\nagreement or commitment, however denominated, not to enforce a patent\n(such as an express permission to practice a patent or covenant not to\nsue for patent infringement).  To \"grant\" such a patent license to a\nparty means to make such an agreement or commitment not to enforce a\npatent against the party.\n\n  If you convey a covered work, knowingly relying on a patent license,\nand the Corresponding Source of the work is not available for anyone\nto copy, free of charge and under the terms of this License, through a\npublicly available network server or other readily accessible means,\nthen you must either (1) cause the Corresponding Source to be so\navailable, or (2) arrange to deprive yourself of the benefit of the\npatent license for this particular work, or (3) arrange, in a manner\nconsistent with the requirements of this License, to extend the patent\nlicense to downstream recipients.  \"Knowingly relying\" means you have\nactual knowledge that, but for the patent license, your conveying the\ncovered work in a country, or your recipient's use of the covered work\nin a country, would infringe one or more identifiable patents in that\ncountry that you have reason to believe are valid.\n\n  If, pursuant to or in connection with a single transaction or\narrangement, you convey, or propagate by procuring conveyance of, a\ncovered work, and grant a patent license to some of the parties\nreceiving the covered work authorizing them to use, propagate, modify\nor convey a specific copy of the covered work, then the patent license\nyou grant is automatically extended to all recipients of the covered\nwork and works based on it.\n\n  A patent license is \"discriminatory\" if it does not include within\nthe scope of its coverage, prohibits the exercise of, or is\nconditioned on the non-exercise of one or more of the rights that are\nspecifically granted under this License.  You may not convey a covered\nwork if you are a party to an arrangement with a third party that is\nin the business of distributing software, under which you make payment\nto the third party based on the extent of your activity of conveying\nthe work, and under which the third party grants, to any of the\nparties who would receive the covered work from you, a discriminatory\npatent license (a) in connection with copies of the covered work\nconveyed by you (or copies made from those copies), or (b) primarily\nfor and in connection with specific products or compilations that\ncontain the covered work, unless you entered into that arrangement,\nor that patent license was granted, prior to 28 March 2007.\n\n  Nothing in this License shall be construed as excluding or limiting\nany implied license or other defenses to infringement that may\notherwise be available to you under applicable patent law.\n\n  12. No Surrender of Others' Freedom.\n\n  If conditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot convey a\ncovered work so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you may\nnot convey it at all.  For example, if you agree to terms that obligate you\nto collect a royalty for further conveying from those to whom you convey\nthe Program, the only way you could satisfy both those terms and this\nLicense would be to refrain entirely from conveying the Program.\n\n  13. Use with the GNU Affero General Public License.\n\n  Notwithstanding any other provision of this License, you have\npermission to link or combine any covered work with a work licensed\nunder version 3 of the GNU Affero General Public License into a single\ncombined work, and to convey the resulting work.  The terms of this\nLicense will continue to apply to the part which is the covered work,\nbut the special requirements of the GNU Affero General Public License,\nsection 13, concerning interaction through a network will apply to the\ncombination as such.\n\n  14. Revised Versions of this License.\n\n  The Free Software Foundation may publish revised and/or new versions of\nthe GNU General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\n  Each version is given a distinguishing version number.  If the\nProgram specifies that a certain numbered version of the GNU General\nPublic License \"or any later version\" applies to it, you have the\noption of following the terms and conditions either of that numbered\nversion or of any later version published by the Free Software\nFoundation.  If the Program does not specify a version number of the\nGNU General Public License, you may choose any version ever published\nby the Free Software Foundation.\n\n  If the Program specifies that a proxy can decide which future\nversions of the GNU General Public License can be used, that proxy's\npublic statement of acceptance of a version permanently authorizes you\nto choose that version for the Program.\n\n  Later license versions may give you additional or different\npermissions.  However, no additional obligations are imposed on any\nauthor or copyright holder as a result of your choosing to follow a\nlater version.\n\n  15. Disclaimer of Warranty.\n\n  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\nAPPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\nHOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\nOF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\nTHE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\nIS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\nALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. Limitation of Liability.\n\n  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS\nTHE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY\nGENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE\nUSE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF\nDATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD\nPARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),\nEVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGES.\n\n  17. Interpretation of Sections 15 and 16.\n\n  If the disclaimer of warranty and limitation of liability provided\nabove cannot be given local legal effect according to their terms,\nreviewing courts shall apply local law that most closely approximates\nan absolute waiver of all civil liability in connection with the\nProgram, unless a warranty or assumption of liability accompanies a\ncopy of the Program in return for a fee.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nstate the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software: you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation, either version 3 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program.  If not, see <http://www.gnu.org/licenses/>.\n\nAlso add information on how to contact you by electronic and paper mail.\n\n  If the program does terminal interaction, make it output a short\nnotice like this when it starts in an interactive mode:\n\n    <program>  Copyright (C) <year>  <name of author>\n    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, your program's commands\nmight be different; for a GUI interface, you would use an \"about box\".\n\n  You should also get your employer (if you work as a programmer) or school,\nif any, to sign a \"copyright disclaimer\" for the program, if necessary.\nFor more information on this, and how to apply and follow the GNU GPL, see\n<http://www.gnu.org/licenses/>.\n\n  The GNU General Public License does not permit incorporating your program\ninto proprietary programs.  If your program is a subroutine library, you\nmay consider it more useful to permit linking proprietary applications with\nthe library.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.  But first, please read\n<http://www.gnu.org/philosophy/why-not-lgpl.html>.\n"
  },
  {
    "path": "README.md",
    "content": "# HiddifyN\nA GUI client for Windows, support [Xray core](https://github.com/XTLS/Xray-core) and [v2fly core](https://github.com/v2fly/v2ray-core) and [others](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)\n![image](https://user-images.githubusercontent.com/114227601/236046684-35a41cbc-9b4f-4dbf-8592-ef0436fbb5b0.png)\n\n\n[![GitHub commit activity](https://img.shields.io/github/commit-activity/m/2dust/v2rayN)](https://github.com/2dust/v2rayN/commits/master)\n[![CodeFactor](https://www.codefactor.io/repository/github/2dust/v2rayn/badge)](https://www.codefactor.io/repository/github/2dust/v2rayn)\n[![GitHub Releases](https://img.shields.io/github/downloads/2dust/v2rayN/latest/total?logo=github)](https://github.com/2dust/v2rayN/releases)\n[![Chat on Telegram](https://img.shields.io/badge/Chat%20on-Telegram-brightgreen.svg)](https://t.me/v2rayn)\n\n### How to use\n- If you are new to this, please download v2rayN-Core.zip from [releases](https://github.com/2dust/v2rayN/releases)\n- Otherwise please download v2rayN.zip (you will also need to download v2ray core into the same folder with HiddifyN.exe)\n- Run HiddifyN.exe\n\n## Requirements  \n- [Microsoft .NET 6.0 Desktop Runtime ](https://download.visualstudio.microsoft.com/download/pr/513d13b7-b456-45af-828b-b7b7981ff462/edf44a743b78f8b54a2cec97ce888346/windowsdesktop-runtime-6.0.15-win-x64.exe)\n- [Supported cores](https://github.com/2dust/v2rayN/wiki/List-of-supported-cores)\n\n### Telegram\n- Channel: [Hiddify](https://t.me/hiddify)\n- Group: [Hiddify Discussion](https://t.me/hiddify_board)\n"
  },
  {
    "path": "v2rayN/.gitattributes",
    "content": "###############################################################################\n# Set default behavior to automatically normalize line endings.\n###############################################################################\n* text=auto\n\n###############################################################################\n# Set default behavior for command prompt diff.\n#\n# This is need for earlier builds of msysgit that does not have it on by\n# default for csharp files.\n# Note: This is only used by command line\n###############################################################################\n#*.cs     diff=csharp\n\n###############################################################################\n# Set the merge driver for project and solution files\n#\n# Merging from the command prompt will add diff markers to the files if there\n# are conflicts (Merging from VS is not affected by the settings below, in VS\n# the diff markers are never inserted). Diff markers may cause the following \n# file extensions to fail to load in VS. An alternative would be to treat\n# these files as binary and thus will always conflict and require user\n# intervention with every merge. To do so, just uncomment the entries below\n###############################################################################\n#*.sln       merge=binary\n#*.csproj    merge=binary\n#*.vbproj    merge=binary\n#*.vcxproj   merge=binary\n#*.vcproj    merge=binary\n#*.dbproj    merge=binary\n#*.fsproj    merge=binary\n#*.lsproj    merge=binary\n#*.wixproj   merge=binary\n#*.modelproj merge=binary\n#*.sqlproj   merge=binary\n#*.wwaproj   merge=binary\n\n###############################################################################\n# behavior for image files\n#\n# image files are treated as binary by default.\n###############################################################################\n#*.jpg   binary\n#*.png   binary\n#*.gif   binary\n\n###############################################################################\n# diff behavior for common document formats\n# \n# Convert binary document formats to text before diffing them. This feature\n# is only available from the command line. Turn it on by uncommenting the \n# entries below.\n###############################################################################\n#*.doc   diff=astextplain\n#*.DOC   diff=astextplain\n#*.docx  diff=astextplain\n#*.DOCX  diff=astextplain\n#*.dot   diff=astextplain\n#*.DOT   diff=astextplain\n#*.pdf   diff=astextplain\n#*.PDF   diff=astextplain\n#*.rtf   diff=astextplain\n#*.RTF   diff=astextplain\n"
  },
  {
    "path": "v2rayN/.gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n##\n## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore\n\n# User-specific files\n*.rsuser\n*.suo\n*.user\n*.userosscache\n*.sln.docstates\n\n# User-specific files (MonoDevelop/Xamarin Studio)\n*.userprefs\n\n# Mono auto generated files\nmono_crash.*\n\n# Build results\n[Dd]ebug/\n[Dd]ebugPublic/\n[Rr]elease/\n[Rr]eleases/\nx64/\nx86/\n[Ww][Ii][Nn]32/\n[Aa][Rr][Mm]/\n[Aa][Rr][Mm]64/\nbld/\n[Bb]in/\n[Oo]bj/\n[Oo]ut/\n[Ll]og/\n[Ll]ogs/\n\n# Visual Studio 2015/2017 cache/options directory\n.vs/\n# Uncomment if you have tasks that create the project's static files in wwwroot\n#wwwroot/\n\n# Visual Studio 2017 auto generated files\nGenerated\\ Files/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n# NUnit\n*.VisualState.xml\nTestResult.xml\nnunit-*.xml\n\n# Build Results of an ATL Project\n[Dd]ebugPS/\n[Rr]eleasePS/\ndlldata.c\n\n# Benchmark Results\nBenchmarkDotNet.Artifacts/\n\n# .NET Core\nproject.lock.json\nproject.fragment.lock.json\nartifacts/\n\n# ASP.NET Scaffolding\nScaffoldingReadMe.txt\n\n# StyleCop\nStyleCopReport.xml\n\n# Files built by Visual Studio\n*_i.c\n*_p.c\n*_h.h\n*.ilk\n*.meta\n*.obj\n*.iobj\n*.pch\n*.pdb\n*.ipdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*_wpftmp.csproj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.svclog\n*.scc\n\n# Chutzpah Test files\n_Chutzpah*\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opendb\n*.opensdf\n*.sdf\n*.cachefile\n*.VC.db\n*.VC.VC.opendb\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n*.sap\n\n# Visual Studio Trace Files\n*.e2e\n\n# TFS 2012 Local Workspace\n$tf/\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n*.DotSettings.user\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# AxoCover is a Code Coverage Tool\n.axoCover/*\n!.axoCover/settings.json\n\n# Coverlet is a free, cross platform Code Coverage Tool\ncoverage*.json\ncoverage*.xml\ncoverage*.info\n\n# Visual Studio code coverage results\n*.coverage\n*.coveragexml\n\n# NCrunch\n_NCrunch_*\n.*crunch*.local.xml\nnCrunchTemp_*\n\n# MightyMoose\n*.mm.*\nAutoTest.Net/\n\n# Web workbench (sass)\n.sass-cache/\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.[Pp]ublish.xml\n*.azurePubxml\n# Note: Comment the next line if you want to checkin your web deploy settings,\n# but database connection strings (with potential passwords) will be unencrypted\n*.pubxml\n*.publishproj\n\n# Microsoft Azure Web App publish settings. Comment the next line if you want to\n# checkin your Azure Web App publish settings, but sensitive information contained\n# in these scripts will be unencrypted\nPublishScripts/\n\n# NuGet Packages\n*.nupkg\n# NuGet Symbol Packages\n*.snupkg\n# The packages folder can be ignored because of Package Restore\n**/[Pp]ackages/*\n# except build/, which is used as an MSBuild target.\n!**/[Pp]ackages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/[Pp]ackages/repositories.config\n# NuGet v3's project.json files produces more ignorable files\n*.nuget.props\n*.nuget.targets\n\n# Microsoft Azure Build Output\ncsx/\n*.build.csdef\n\n# Microsoft Azure Emulator\necf/\nrcf/\n\n# Windows Store app package directories and files\nAppPackages/\nBundleArtifacts/\nPackage.StoreAssociation.xml\n_pkginfo.txt\n*.appx\n*.appxbundle\n*.appxupload\n\n# Visual Studio cache files\n# files ending in .cache can be ignored\n*.[Cc]ache\n# but keep track of directories ending in .cache\n!?*.[Cc]ache/\n\n# Others\nClientBin/\n~$*\n*~\n*.dbmdl\n*.dbproj.schemaview\n*.jfm\n*.pfx\n*.publishsettings\norleans.codegen.cs\n\n# Including strong name files can present a security risk\n# (https://github.com/github/gitignore/pull/2483#issue-259490424)\n#*.snk\n\n# Since there are multiple workflows, uncomment next line to ignore bower_components\n# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)\n#bower_components/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file\n# to a newer Visual Studio version. Backup files are not needed,\n# because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\nServiceFabricBackup/\n*.rptproj.bak\n\n# SQL Server files\n*.mdf\n*.ldf\n*.ndf\n\n# Business Intelligence projects\n*.rdl.data\n*.bim.layout\n*.bim_*.settings\n*.rptproj.rsuser\n*- [Bb]ackup.rdl\n*- [Bb]ackup ([0-9]).rdl\n*- [Bb]ackup ([0-9][0-9]).rdl\n\n# Microsoft Fakes\nFakesAssemblies/\n\n# GhostDoc plugin setting file\n*.GhostDoc.xml\n\n# Node.js Tools for Visual Studio\n.ntvs_analysis.dat\nnode_modules/\n\n# Visual Studio 6 build log\n*.plg\n\n# Visual Studio 6 workspace options file\n*.opt\n\n# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)\n*.vbw\n\n# Visual Studio LightSwitch build output\n**/*.HTMLClient/GeneratedArtifacts\n**/*.DesktopClient/GeneratedArtifacts\n**/*.DesktopClient/ModelManifest.xml\n**/*.Server/GeneratedArtifacts\n**/*.Server/ModelManifest.xml\n_Pvt_Extensions\n\n# Paket dependency manager\n.paket/paket.exe\npaket-files/\n\n# FAKE - F# Make\n.fake/\n\n# CodeRush personal settings\n.cr/personal\n\n# Python Tools for Visual Studio (PTVS)\n__pycache__/\n*.pyc\n\n# Cake - Uncomment if you are using it\n# tools/**\n# !tools/packages.config\n\n# Tabs Studio\n*.tss\n\n# Telerik's JustMock configuration file\n*.jmconfig\n\n# BizTalk build output\n*.btp.cs\n*.btm.cs\n*.odx.cs\n*.xsd.cs\n\n# OpenCover UI analysis results\nOpenCover/\n\n# Azure Stream Analytics local run output\nASALocalRun/\n\n# MSBuild Binary and Structured Log\n*.binlog\n\n# NVidia Nsight GPU debugger configuration file\n*.nvuser\n\n# MFractors (Xamarin productivity tool) working folder\n.mfractor/\n\n# Local History for Visual Studio\n.localhistory/\n\n# BeatPulse healthcheck temp database\nhealthchecksdb\n\n# Backup folder for Package Reference Convert tool in Visual Studio 2017\nMigrationBackup/\n\n# Ionide (cross platform F# VS Code tools) working folder\n.ionide/\n\n# Fody - auto-generated XML schema\nFodyWeavers.xsd"
  },
  {
    "path": "v2rayN/HiddifyRestartN/HiddifyRestartN.csproj",
    "content": "<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <OutputType>Exe</OutputType>\n    <TargetFramework>net6.0</TargetFramework>\n    <ImplicitUsings>enable</ImplicitUsings>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n\n</Project>\n"
  },
  {
    "path": "v2rayN/HiddifyRestartN/Program.cs",
    "content": "﻿using System.Diagnostics;\n\n// This program is jsut for restarting main program\ntry\n{\n    // Killing\n\n    // Get running main program process id\n    int mainProgramProcessID = int.Parse(Environment.GetCommandLineArgs()[1]);\n    // Get process\n    //var mainProcess = Process.GetProcessById(mainProgramProcessID);\n    // Kill process\n    //mainProcess.Kill();\n\n    // Running\n\n    // Main program exe path\n    string mainProgramPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, \"HiddifyN.exe\"));\n    // Command to run program\n    string cmd = $\"{mainProgramPath}\";\n\n    // Run again\n    Process.Start(cmd);\n}\ncatch (Exception err)\n{\n    Console.Error.WriteLine(err);\n}"
  },
  {
    "path": "v2rayN/HiddifyRestartN/Properties/launchSettings.json",
    "content": "{\n  \"profiles\": {\n    \"HiddifyRestartN\": {\n      \"commandName\": \"Project\",\n      \"commandLineArgs\": \"2342 --admin\",\n      \"workingDirectory\": \"C:\\\\Users\\\\me\\\\Desktop\\\\HiddifyDesktopN\\\\v2rayN\\\\v2rayN\\\\bin\\\\Debug\\\\net6.0-windows\"\n    }\n  }\n}"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/HiddifyUpgradeN.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n\t<TargetFramework>net6.0-windows</TargetFramework>\n\t<OutputType>WinExe</OutputType>\n\t<UseWindowsForms>true</UseWindowsForms>\t    \n\t<Copyright>Copyright © 2019-2023 (GPLv3)</Copyright>\n\t<FileVersion>1.1.0.0</FileVersion>\n\t<ApplicationManifest>app.manifest</ApplicationManifest>\n\t<Nullable>enable</Nullable>\n\t<AssemblyName>HiddifyUpgradeN</AssemblyName>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/MainForm.Designer.cs",
    "content": "﻿namespace v2rayUpgrade\n{\n    partial class MainForm\n    {\n        /// <summary>\n        /// 必需的设计器变量。\n        /// </summary>\n        private System.ComponentModel.IContainer components = null;\n\n        /// <summary>\n        /// 清理所有正在使用的资源。\n        /// </summary>\n        /// <param name=\"disposing\">如果应释放托管资源，为 true；否则为 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 窗体设计器生成的代码\n\n        /// <summary>\n        /// 设计器支持所需的方法 - 不要修改\n        /// 使用代码编辑器修改此方法的内容。\n        /// </summary>\n        private void InitializeComponent()\n        {\n            this.btnClose = new System.Windows.Forms.Button();\n            this.btnOK = new System.Windows.Forms.Button();\n            this.label1 = new System.Windows.Forms.Label();\n            this.label2 = new System.Windows.Forms.Label();\n            this.SuspendLayout();\n            // \n            // btnClose\n            // \n            this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;\n            this.btnClose.Font = new System.Drawing.Font(\"微软雅黑\", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\n            this.btnClose.ImeMode = System.Windows.Forms.ImeMode.NoControl;\n            this.btnClose.Location = new System.Drawing.Point(367, 118);\n            this.btnClose.Name = \"btnClose\";\n            this.btnClose.Size = new System.Drawing.Size(184, 89);\n            this.btnClose.TabIndex = 1;\n            this.btnClose.Text = \"&Exit(退出)\";\n            this.btnClose.UseVisualStyleBackColor = true;\n            this.btnClose.Click += new System.EventHandler(this.btnClose_Click);\n            // \n            // btnOK\n            // \n            this.btnOK.Font = new System.Drawing.Font(\"微软雅黑\", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\n            this.btnOK.ImeMode = System.Windows.Forms.ImeMode.NoControl;\n            this.btnOK.Location = new System.Drawing.Point(81, 118);\n            this.btnOK.Name = \"btnOK\";\n            this.btnOK.Size = new System.Drawing.Size(184, 89);\n            this.btnOK.TabIndex = 0;\n            this.btnOK.Text = \"&Upgrade(升级)\";\n            this.btnOK.UseVisualStyleBackColor = true;\n            this.btnOK.Click += new System.EventHandler(this.btnOK_Click);\n            // \n            // label1\n            // \n            this.label1.AutoSize = true;\n            this.label1.Font = new System.Drawing.Font(\"微软雅黑\", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\n            this.label1.Location = new System.Drawing.Point(79, 64);\n            this.label1.Name = \"label1\";\n            this.label1.Size = new System.Drawing.Size(205, 15);\n            this.label1.TabIndex = 8;\n            this.label1.Text = \"升级成功后将自动重启v2rayN\";\n            // \n            // label2\n            // \n            this.label2.AutoSize = true;\n            this.label2.Font = new System.Drawing.Font(\"微软雅黑\", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));\n            this.label2.Location = new System.Drawing.Point(79, 37);\n            this.label2.Name = \"label2\";\n            this.label2.Size = new System.Drawing.Size(471, 15);\n            this.label2.TabIndex = 9;\n            this.label2.Text = \"v2rayN will restart automatically after successful upgrade\";\n            // \n            // MainForm\n            // \n            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);\n            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;\n            this.ClientSize = new System.Drawing.Size(616, 284);\n            this.Controls.Add(this.label2);\n            this.Controls.Add(this.label1);\n            this.Controls.Add(this.btnClose);\n            this.Controls.Add(this.btnOK);\n            this.Name = \"MainForm\";\n            this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;\n            this.Text = \"v2rayUpgrade\";\n            this.ResumeLayout(false);\n            this.PerformLayout();\n\n        }\n\n        #endregion\n\n        private System.Windows.Forms.Button btnClose;\n        private System.Windows.Forms.Button btnOK;\n        private System.Windows.Forms.Label label1;\n        private System.Windows.Forms.Label label2;\n    }\n}\n\n"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/MainForm.cs",
    "content": "﻿using System;\nusing System.Diagnostics;\nusing System.IO;\nusing System.IO.Compression;\nusing System.Text;\nusing System.Web;\nusing System.Windows.Forms;\n\nnamespace v2rayUpgrade\n{\n    public partial class MainForm : Form\n    {\n        private readonly string defaultFilename = \"v2ray-windows.zip\";\n        private string? fileName;\n\n        public MainForm(string[] args)\n        {\n            InitializeComponent();\n            if (args.Length > 0)\n            {\n                fileName = HttpUtility.UrlDecode(string.Join(\" \", args));\n            }\n            else\n            {\n                fileName = defaultFilename;\n            }\n        }\n\n        private void ShowWarn(string message)\n        {\n            MessageBox.Show(message, \"\", MessageBoxButtons.OK, MessageBoxIcon.Warning);\n        }\n\n        private void btnOK_Click(object sender, EventArgs e)\n        {\n            try\n            {\n                Process[] existing = Process.GetProcessesByName(\"HiddifyN\");\n                foreach (Process p in existing)\n                {\n                    string? path = p.MainModule?.FileName;\n                    if (path == GetPath(\"HiddifyN.exe\"))\n                    {\n                        p.Kill();\n                        p.WaitForExit(100);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                // Access may be denied without admin right. The user may not be an administrator.\n                ShowWarn(\"Failed to close v2rayN(关闭v2rayN失败).\\n\" +\n                    \"Close it manually, or the upgrade may fail.(请手动关闭正在运行的v2rayN，否则可能升级失败。\\n\\n\" + ex.StackTrace);\n            }\n\n            if (!File.Exists(fileName))\n            {\n                if (File.Exists(defaultFilename))\n                {\n                    fileName = defaultFilename;\n                }\n                else\n                {\n                    ShowWarn(\"Upgrade Failed, File Not Exist(升级失败,文件不存在).\");\n                    return;\n                }\n            }\n\n            StringBuilder sb = new();\n            try\n            {\n                string thisAppOldFile = $\"{Application.ExecutablePath}.tmp\";\n                File.Delete(thisAppOldFile);\n                string startKey = \"v2rayN/\";\n\n                using ZipArchive archive = ZipFile.OpenRead(fileName);\n                foreach (ZipArchiveEntry entry in archive.Entries)\n                {\n                    try\n                    {\n                        if (entry.Length == 0)\n                        {\n                            continue;\n                        }\n                        string fullName = entry.FullName;\n                        if (fullName.StartsWith(startKey))\n                        {\n                            fullName = fullName[startKey.Length..];\n                        }\n                        if (string.Equals(Application.ExecutablePath, GetPath(fullName), StringComparison.OrdinalIgnoreCase))\n                        {\n                            File.Move(Application.ExecutablePath, thisAppOldFile);\n                        }\n\n                        string entryOuputPath = GetPath(fullName);\n                        Directory.CreateDirectory(Path.GetDirectoryName(entryOuputPath)!);\n                        entry.ExtractToFile(entryOuputPath, true);\n                    }\n                    catch (Exception ex)\n                    {\n                        sb.Append(ex.StackTrace);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                ShowWarn(\"Upgrade Failed(升级失败).\" + ex.StackTrace);\n                return;\n            }\n            if (sb.Length > 0)\n            {\n                ShowWarn(\"Upgrade Failed,Hold ctrl + c to copy to clipboard.\\n\" +\n                    \"(升级失败,按住ctrl+c可以复制到剪贴板).\" + sb.ToString());\n                return;\n            }\n\n            Process.Start(\"HiddifyN.exe\");\n            MessageBox.Show(\"Upgrade successed(升级成功)\", \"\", MessageBoxButtons.OK, MessageBoxIcon.Information);\n\n            Close();\n        }\n\n        private void btnClose_Click(object sender, EventArgs e)\n        {\n            Close();\n        }\n\n        public static string GetExePath()\n        {\n            return Application.ExecutablePath;\n        }\n\n        public static string StartupPath()\n        {\n            return Application.StartupPath;\n        }\n\n        public static string GetPath(string fileName)\n        {\n            string startupPath = StartupPath();\n            if (string.IsNullOrEmpty(fileName))\n            {\n                return startupPath;\n            }\n            return Path.Combine(startupPath, fileName);\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/MainForm.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</root>"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/Program.cs",
    "content": "﻿using System;\nusing System.Windows.Forms;\n\nnamespace v2rayUpgrade\n{\n    internal static class Program\n    {\n        /// <summary>\n        /// 应用程序的主入口点。\n        /// </summary>\n        [STAThread]\n        private static void Main(string[] args)\n        {\n            Application.EnableVisualStyles();\n            Application.SetHighDpiMode(HighDpiMode.SystemAware);\n            Application.SetCompatibleTextRenderingDefault(false);\n            Application.Run(new MainForm(args));\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/Properties/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:4.0.30319.42000\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace v2rayUpgrade.Properties {\n    using System;\n    \n    \n    /// <summary>\n    ///   一个强类型的资源类，用于查找本地化的字符串等。\n    /// </summary>\n    // 此类是由 StronglyTypedResourceBuilder\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\n    // 若要添加或移除成员，请编辑 .ResX 文件，然后重新运行 ResGen\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"16.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   返回此类使用的缓存的 ResourceManager 实例。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"v2rayUpgrade.Properties.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   重写当前线程的 CurrentUICulture 属性\n        ///   重写当前线程的 CurrentUICulture 属性。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/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.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: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\" type=\"xsd:string\" />\n              <xsd:attribute name=\"type\" type=\"xsd:string\" />\n              <xsd:attribute name=\"mimetype\" type=\"xsd:string\" />\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\" 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>2.0</value>\n  </resheader>\n  <resheader name=\"reader\">\n    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n  <resheader name=\"writer\">\n    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>\n  </resheader>\n</root>"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/Properties/Settings.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:4.0.30319.42000\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace v2rayUpgrade.Properties {\n    \n    \n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator\", \"16.3.0.0\")]\n    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {\n        \n        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));\n        \n        public static Settings Default {\n            get {\n                return defaultInstance;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/Properties/Settings.settings",
    "content": "﻿<?xml version='1.0' encoding='utf-8'?>\n<SettingsFile xmlns=\"http://schemas.microsoft.com/VisualStudio/2004/01/settings\" CurrentProfile=\"(Default)\">\n  <Profiles>\n    <Profile Name=\"(Default)\" />\n  </Profiles>\n  <Settings />\n</SettingsFile>\n"
  },
  {
    "path": "v2rayN/HiddifyUpgradeN/app.manifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\" xmlns:asmv3=\"urn:schemas-microsoft-com:asm.v3\">\n  <asmv3:application>\n    <asmv3:windowsSettings>\n      <dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true</dpiAware>\n      <dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2</dpiAwareness>\n    </asmv3:windowsSettings>\n  </asmv3:application>\n</assembly>"
  },
  {
    "path": "v2rayN/PacLib/PacHandler.cs",
    "content": "﻿using System;\nusing System.IO;\nusing System.Net.Sockets;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\n\nnamespace PacLib;\n\npublic class PacHandler\n{\n    private static string _configPath;\n    private static int _httpPort;\n    private static int _pacPort;\n    private static TcpListener? _tcpListener;\n    private static string _pacText;\n    private static bool _isRunning;\n    private static bool _needRestart = true;\n\n    public static void Start(string configPath, int httpPort, int pacPort)\n    {\n        _needRestart = (configPath != _configPath || httpPort != _httpPort || pacPort != _pacPort || !_isRunning);\n\n        _configPath = configPath;\n        _httpPort = httpPort;\n        _pacPort = pacPort;\n\n        InitText();\n\n        if (_needRestart)\n        {\n            Stop();\n            RunListener();\n        }\n    }\n\n    private static void InitText()\n    {\n        var path = Path.Combine(_configPath, \"pac.txt\");\n        if (!File.Exists(path))\n        {\n            File.AppendAllText(path, Resources.ResourceManager.GetString(\"pac\"));\n        }\n\n        _pacText = File.ReadAllText(path).Replace(\"__PROXY__\", $\"PROXY 127.0.0.1:{_httpPort};DIRECT;\");\n    }\n\n    private static void RunListener()\n    {\n        _tcpListener = TcpListener.Create(_pacPort);\n        _isRunning = true;\n        _tcpListener.Start();\n        Task.Factory.StartNew(() =>\n        {\n            while (_isRunning)\n            {\n                try\n                {\n                    if (!_tcpListener.Pending())\n                    {\n                        Thread.Sleep(10);\n                        continue;\n                    }\n\n                    var client = _tcpListener.AcceptTcpClient();\n                    Task.Run(() =>\n                    {\n                        var stream = client.GetStream();\n                        var sb = new StringBuilder();\n                        sb.AppendLine(\"HTTP/1.0 200 OK\");\n                        sb.AppendLine(\"Content-type:application/x-ns-proxy-autoconfig\");\n                        sb.AppendLine(\"Connection:close\");\n                        sb.AppendLine(\"Content-Length:\" + Encoding.UTF8.GetByteCount(_pacText));\n                        sb.AppendLine();\n                        sb.Append(_pacText);\n                        var content = Encoding.UTF8.GetBytes(sb.ToString());\n                        stream.Write(content, 0, content.Length);\n                        stream.Flush();\n                    });\n                }\n                catch (Exception e)\n                {\n                }\n            }\n        }, TaskCreationOptions.LongRunning);\n    }\n\n    public static void Stop()\n    {\n        if (_tcpListener != null)\n        {\n            try\n            {\n                _isRunning = false;\n                _tcpListener.Stop();\n                _tcpListener = null;\n            }\n            catch (Exception e)\n            {\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/PacLib/PacLib.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n  <PropertyGroup>\n    <TargetFramework>net6.0-windows</TargetFramework>\n    <Nullable>enable</Nullable>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <Compile Update=\"Resources.Designer.cs\">\n      <DesignTime>True</DesignTime>\n      <AutoGen>True</AutoGen>\n      <DependentUpon>Resources.resx</DependentUpon>\n    </Compile> \n    <EmbeddedResource Update=\"Resources.resx\">\n      <Generator>ResXFileCodeGenerator</Generator>\n      <LastGenOutput>Resources.Designer.cs</LastGenOutput>\n    </EmbeddedResource>\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "v2rayN/PacLib/Resources/pac.txt",
    "content": "var proxy = '__PROXY__';\nvar rules = [\n    [\n        [],\n        []\n    ],\n    [\n        [\n            \"aftygh.gov.tw\",\n            \"aide.gov.tw\",\n            \"aliyun.com\",\n            \"arte.gov.tw\",\n            \"baidu.com\",\n            \"chinaso.com\",\n            \"chinaz.com\",\n            \"chukuang.gov.tw\",\n            \"cycab.gov.tw\",\n            \"dbnsa.gov.tw\",\n            \"df.gov.tw\",\n            \"eastcoast-nsa.gov.tw\",\n            \"erv-nsa.gov.tw\",\n            \"grb.gov.tw\",\n            \"haosou.com\",\n            \"haygo.com\",\n            \"hchcc.gov.tw\",\n            \"hsinchu-cc.gov.tw\",\n            \"iner.gov.tw\",\n            \"ip.cn\",\n            \"jike.com\",\n            \"jpush.cn\",\n            \"klsio.gov.tw\",\n            \"kmseh.gov.tw\",\n            \"locql.com\",\n            \"lungtanhr.gov.tw\",\n            \"maolin-nsa.gov.tw\",\n            \"matsu-news.gov.tw\",\n            \"matsu-nsa.gov.tw\",\n            \"matsucc.gov.tw\",\n            \"moe.gov.tw\",\n            \"nankan.gov.tw\",\n            \"ncree.gov.tw\",\n            \"necoast-nsa.gov.tw\",\n            \"ner.gov.tw\",\n            \"nmmba.gov.tw\",\n            \"nmp.gov.tw\",\n            \"nmvttc.gov.tw\",\n            \"northguan-nsa.gov.tw\",\n            \"npm.gov.tw\",\n            \"nstm.gov.tw\",\n            \"ntdmh.gov.tw\",\n            \"ntl.gov.tw\",\n            \"ntsec.gov.tw\",\n            \"ntuh.gov.tw\",\n            \"nvri.gov.tw\",\n            \"nyc.gov.tw\",\n            \"penghu-nsa.gov.tw\",\n            \"post.gov.tw\",\n            \"qq.com\",\n            \"simplecd.me\",\n            \"sina.cn\",\n            \"sina.com.cn\",\n            \"siraya-nsa.gov.tw\",\n            \"sl-reverse.com\",\n            \"so.com\",\n            \"sogou.com\",\n            \"soso.com\",\n            \"stdtime.gov.tw\",\n            \"sunmoonlake.gov.tw\",\n            \"syniumsoftware.com\",\n            \"taitung-house.gov.tw\",\n            \"taoyuan.gov.tw\",\n            \"tphcc.gov.tw\",\n            \"trimt-nsa.gov.tw\",\n            \"uluai.com.cn\",\n            \"vghks.gov.tw\",\n            \"vghtc.gov.tw\",\n            \"vghtpe.gov.tw\",\n            \"wallproxy.com.cn\",\n            \"wanfang.gov.tw\",\n            \"weibo.com\",\n            \"yahoo.cn\",\n            \"yatsen.gov.tw\",\n            \"yda.gov.tw\",\n            \"youdao.com\",\n            \"zhongsou.com\"\n        ],\n        [\n            \"000webhost.com\",\n            \"030buy.com\",\n            \"0rz.tw\",\n            \"1-apple.com.tw\",\n            \"10.tt\",\n            \"1000giri.net\",\n            \"100ke.org\",\n            \"10beasts.net\",\n            \"10conditionsoflove.com\",\n            \"10musume.com\",\n            \"123rf.com\",\n            \"12bet.com\",\n            \"12vpn.com\",\n            \"12vpn.net\",\n            \"1337x.to\",\n            \"138.com\",\n            \"141hongkong.com\",\n            \"141jj.com\",\n            \"141tube.com\",\n            \"1688.com.au\",\n            \"173ng.com\",\n            \"177pic.info\",\n            \"17t17p.com\",\n            \"18board.com\",\n            \"18board.info\",\n            \"18onlygirls.com\",\n            \"18p2p.com\",\n            \"18virginsex.com\",\n            \"1949er.org\",\n            \"1984.city\",\n            \"1984bbs.com\",\n            \"1984bbs.org\",\n            \"1991way.com\",\n            \"1998cdp.org\",\n            \"1bao.org\",\n            \"1dumb.com\",\n            \"1e100.net\",\n            \"1eew.com\",\n            \"1mobile.com\",\n            \"1mobile.tw\",\n            \"1pondo.tv\",\n            \"2-hand.info\",\n            \"2000fun.com\",\n            \"2008xianzhang.info\",\n            \"2017.hk\",\n            \"2021hkcharter.com\",\n            \"2047.name\",\n            \"21andy.com\",\n            \"21join.com\",\n            \"21pron.com\",\n            \"21sextury.com\",\n            \"228.net.tw\",\n            \"233abc.com\",\n            \"24hrs.ca\",\n            \"24smile.org\",\n            \"25u.com\",\n            \"2lipstube.com\",\n            \"2shared.com\",\n            \"2waky.com\",\n            \"3-a.net\",\n            \"30boxes.com\",\n            \"315lz.com\",\n            \"32red.com\",\n            \"36rain.com\",\n            \"3a5a.com\",\n            \"3arabtv.com\",\n            \"3boys2girls.com\",\n            \"3d-game.com\",\n            \"3proxy.ru\",\n            \"3ren.ca\",\n            \"3tui.net\",\n            \"404museum.com\",\n            \"43110.cf\",\n            \"466453.com\",\n            \"4bluestones.biz\",\n            \"4chan.com\",\n            \"4dq.com\",\n            \"4everproxy.com\",\n            \"4irc.com\",\n            \"4mydomain.com\",\n            \"4pu.com\",\n            \"4rbtv.com\",\n            \"4shared.com\",\n            \"4sqi.net\",\n            \"50webs.com\",\n            \"51.ca\",\n            \"51jav.org\",\n            \"51luoben.com\",\n            \"5278.cc\",\n            \"5299.tv\",\n            \"5aimiku.com\",\n            \"5i01.com\",\n            \"5isotoi5.org\",\n            \"5maodang.com\",\n            \"63i.com\",\n            \"64museum.org\",\n            \"64tianwang.com\",\n            \"64wiki.com\",\n            \"66.ca\",\n            \"666kb.com\",\n            \"6do.news\",\n            \"6park.com\",\n            \"6parkbbs.com\",\n            \"6parker.com\",\n            \"6parknews.com\",\n            \"7-zip.org\",\n            \"7capture.com\",\n            \"7cow.com\",\n            \"8-d.com\",\n            \"85cc.net\",\n            \"85cc.us\",\n            \"85st.com\",\n            \"881903.com\",\n            \"888.com\",\n            \"888poker.com\",\n            \"89-64.org\",\n            \"8964museum.com\",\n            \"8news.com.tw\",\n            \"8z1.net\",\n            \"9001700.com\",\n            \"908taiwan.org\",\n            \"91porn.com\",\n            \"91vps.club\",\n            \"92ccav.com\",\n            \"991.com\",\n            \"99btgc01.com\",\n            \"99cn.info\",\n            \"9bis.com\",\n            \"9bis.net\",\n            \"9cache.com\",\n            \"9gag.com\",\n            \"9news.com.au\",\n            \"a-normal-day.com\",\n            \"aamacau.com\",\n            \"abc.com\",\n            \"abc.net.au\",\n            \"abc.xyz\",\n            \"abchinese.com\",\n            \"abclite.net\",\n            \"abebooks.com\",\n            \"ablwang.com\",\n            \"aboluowang.com\",\n            \"about.google\",\n            \"aboutgfw.com\",\n            \"abs.edu\",\n            \"acast.com\",\n            \"accim.org\",\n            \"accountkit.com\",\n            \"aceros-de-hispania.com\",\n            \"acevpn.com\",\n            \"acg18.me\",\n            \"acgbox.org\",\n            \"acgkj.com\",\n            \"acgnx.se\",\n            \"acmedia365.com\",\n            \"acmetoy.com\",\n            \"acnw.com.au\",\n            \"actfortibet.org\",\n            \"actimes.com.au\",\n            \"activpn.com\",\n            \"aculo.us\",\n            \"adcex.com\",\n            \"addictedtocoffee.de\",\n            \"addyoutube.com\",\n            \"adelaidebbs.com\",\n            \"admob.com\",\n            \"adpl.org.hk\",\n            \"ads-twitter.com\",\n            \"adsense.com\",\n            \"adult-sex-games.com\",\n            \"adultfriendfinder.com\",\n            \"adultkeep.net\",\n            \"advanscene.com\",\n            \"advertfan.com\",\n            \"advertisercommunity.com\",\n            \"ae.org\",\n            \"aenhancers.com\",\n            \"aex.com\",\n            \"af.mil\",\n            \"afantibbs.com\",\n            \"afr.com\",\n            \"afreecatv.com\",\n            \"agnesb.fr\",\n            \"agoogleaday.com\",\n            \"agro.hk\",\n            \"ai-kan.net\",\n            \"ai-wen.net\",\n            \"ai.google\",\n            \"aiph.net\",\n            \"airasia.com\",\n            \"airconsole.com\",\n            \"aircrack-ng.org\",\n            \"airvpn.org\",\n            \"aisex.com\",\n            \"ait.org.tw\",\n            \"aiweiwei.com\",\n            \"aiweiweiblog.com\",\n            \"ajsands.com\",\n            \"akademiye.org\",\n            \"akamai.net\",\n            \"akamaihd.net\",\n            \"akamaistream.net\",\n            \"akamaized.net\",\n            \"akiba-online.com\",\n            \"akiba-web.com\",\n            \"akow.org\",\n            \"al-islam.com\",\n            \"al-qimmah.net\",\n            \"alabout.com\",\n            \"alanhou.com\",\n            \"alarab.qa\",\n            \"alasbarricadas.org\",\n            \"alexlur.org\",\n            \"alforattv.net\",\n            \"alhayat.com\",\n            \"alicejapan.co.jp\",\n            \"aliengu.com\",\n            \"alive.bar\",\n            \"alkasir.com\",\n            \"all4mom.org\",\n            \"allcoin.com\",\n            \"allconnected.co\",\n            \"alldrawnsex.com\",\n            \"allervpn.com\",\n            \"allfinegirls.com\",\n            \"allgirlmassage.com\",\n            \"allgirlsallowed.org\",\n            \"allgravure.com\",\n            \"alliance.org.hk\",\n            \"allinfa.com\",\n            \"alljackpotscasino.com\",\n            \"allmovie.com\",\n            \"allowed.org\",\n            \"almasdarnews.com\",\n            \"almostmy.com\",\n            \"alphaporno.com\",\n            \"alternate-tools.com\",\n            \"alternativeto.net\",\n            \"altrec.com\",\n            \"alvinalexander.com\",\n            \"alwaysdata.com\",\n            \"alwaysdata.net\",\n            \"alwaysvpn.com\",\n            \"am730.com.hk\",\n            \"amazon.co.jp\",\n            \"amazon.com\",\n            \"amazonaws.com\",\n            \"ameblo.jp\",\n            \"america.gov\",\n            \"american.edu\",\n            \"americangreencard.com\",\n            \"americanunfinished.com\",\n            \"americorps.gov\",\n            \"amiblockedornot.com\",\n            \"amigobbs.net\",\n            \"amitabhafoundation.us\",\n            \"amnesty.org\",\n            \"amnesty.org.hk\",\n            \"amnesty.tw\",\n            \"amnestyusa.org\",\n            \"amnyemachen.org\",\n            \"amoiist.com\",\n            \"ampproject.org\",\n            \"amtb-taipei.org\",\n            \"anchor.fm\",\n            \"anchorfree.com\",\n            \"ancsconf.org\",\n            \"andfaraway.net\",\n            \"android-x86.org\",\n            \"android.com\",\n            \"androidify.com\",\n            \"androidplus.co\",\n            \"androidtv.com\",\n            \"andygod.com\",\n            \"angela-merkel.de\",\n            \"angelfire.com\",\n            \"angola.org\",\n            \"angularjs.org\",\n            \"animecrazy.net\",\n            \"aniscartujo.com\",\n            \"annatam.com\",\n            \"anobii.com\",\n            \"anontext.com\",\n            \"anonymitynetwork.com\",\n            \"anonymizer.com\",\n            \"anonymouse.org\",\n            \"anpopo.com\",\n            \"answering-islam.org\",\n            \"antd.org\",\n            \"anthonycalzadilla.com\",\n            \"anti1984.com\",\n            \"antichristendom.com\",\n            \"antiwave.net\",\n            \"anws.gov.tw\",\n            \"anyporn.com\",\n            \"anysex.com\",\n            \"ao3.org\",\n            \"aobo.com.au\",\n            \"aofriend.com\",\n            \"aofriend.com.au\",\n            \"aojiao.org\",\n            \"aol.ca\",\n            \"aol.co.uk\",\n            \"aol.com\",\n            \"aolnews.com\",\n            \"aomiwang.com\",\n            \"ap.org\",\n            \"apartmentratings.com\",\n            \"apartments.com\",\n            \"apat1989.org\",\n            \"apetube.com\",\n            \"api.ai\",\n            \"apiary.io\",\n            \"apigee.com\",\n            \"apk-dl.com\",\n            \"apk.support\",\n            \"apkcombo.com\",\n            \"apkmirror.com\",\n            \"apkmonk.com\",\n            \"apkplz.com\",\n            \"apkpure.com\",\n            \"aplusvpn.com\",\n            \"appbrain.com\",\n            \"appdownloader.net\",\n            \"appledaily.com\",\n            \"appledaily.com.hk\",\n            \"appledaily.com.tw\",\n            \"appshopper.com\",\n            \"appsocks.net\",\n            \"appspot.com\",\n            \"appsto.re\",\n            \"aptoide.com\",\n            \"archive.fo\",\n            \"archive.is\",\n            \"archive.li\",\n            \"archive.org\",\n            \"archive.ph\",\n            \"archive.today\",\n            \"archiveofourown.com\",\n            \"archiveofourown.org\",\n            \"archives.gov\",\n            \"archives.gov.tw\",\n            \"arctosia.com\",\n            \"areca-backup.org\",\n            \"arena.taipei\",\n            \"arethusa.su\",\n            \"arlingtoncemetery.mil\",\n            \"army.mil\",\n            \"art4tibet1998.org\",\n            \"arte.tv\",\n            \"artofpeacefoundation.org\",\n            \"artstation.com\",\n            \"artsy.net\",\n            \"asacp.org\",\n            \"asdfg.jp\",\n            \"asg.to\",\n            \"asia-gaming.com\",\n            \"asiaharvest.org\",\n            \"asianage.com\",\n            \"asianews.it\",\n            \"asianfreeforum.com\",\n            \"asiansexdiary.com\",\n            \"asianspiss.com\",\n            \"asianwomensfilm.de\",\n            \"asiaone.com\",\n            \"asiatgp.com\",\n            \"asiatoday.us\",\n            \"askstudent.com\",\n            \"askynz.net\",\n            \"aspi.org.au\",\n            \"aspistrategist.org.au\",\n            \"assembla.com\",\n            \"assimp.org\",\n            \"astrill.com\",\n            \"atc.org.au\",\n            \"atchinese.com\",\n            \"atdmt.com\",\n            \"atgfw.org\",\n            \"athenaeizou.com\",\n            \"atlanta168.com\",\n            \"atlaspost.com\",\n            \"atnext.com\",\n            \"audionow.com\",\n            \"authorizeddns.net\",\n            \"authorizeddns.org\",\n            \"authorizeddns.us\",\n            \"autodraw.com\",\n            \"av-e-body.com\",\n            \"av.com\",\n            \"av.movie\",\n            \"avaaz.org\",\n            \"avbody.tv\",\n            \"avcity.tv\",\n            \"avcool.com\",\n            \"avdb.in\",\n            \"avdb.tv\",\n            \"avfantasy.com\",\n            \"avg.com\",\n            \"avgle.com\",\n            \"avidemux.org\",\n            \"avmo.pw\",\n            \"avmoo.com\",\n            \"avmoo.net\",\n            \"avmoo.pw\",\n            \"avoision.com\",\n            \"avyahoo.com\",\n            \"axios.com\",\n            \"axureformac.com\",\n            \"azerbaycan.tv\",\n            \"azerimix.com\",\n            \"azubu.tv\",\n            \"azurewebsites.net\",\n            \"b-ok.cc\",\n            \"b0ne.com\",\n            \"baby-kingdom.com\",\n            \"babylonbee.com\",\n            \"babynet.com.hk\",\n            \"backchina.com\",\n            \"backpackers.com.tw\",\n            \"backtotiananmen.com\",\n            \"badiucao.com\",\n            \"badjojo.com\",\n            \"badoo.com\",\n            \"baidu.jp\",\n            \"baijie.org\",\n            \"bailandaily.com\",\n            \"baixing.me\",\n            \"bakgeekhome.tk\",\n            \"banana-vpn.com\",\n            \"band.us\",\n            \"bandcamp.com\",\n            \"bandwagonhost.com\",\n            \"bangbrosnetwork.com\",\n            \"bangchen.net\",\n            \"bangdream.space\",\n            \"bangkokpost.com\",\n            \"bangyoulater.com\",\n            \"bankmobilevibe.com\",\n            \"bannedbook.org\",\n            \"bannednews.org\",\n            \"banorte.com\",\n            \"baramangaonline.com\",\n            \"barenakedislam.com\",\n            \"barnabu.co.uk\",\n            \"barton.de\",\n            \"bastillepost.com\",\n            \"bayvoice.net\",\n            \"baywords.com\",\n            \"bb-chat.tv\",\n            \"bbc.co.uk\",\n            \"bbc.com\",\n            \"bbc.in\",\n            \"bbcchinese.com\",\n            \"bbchat.tv\",\n            \"bbci.co.uk\",\n            \"bbg.gov\",\n            \"bbkz.com\",\n            \"bbnradio.org\",\n            \"bbs-tw.com\",\n            \"bbsdigest.com\",\n            \"bbsfeed.com\",\n            \"bbsland.com\",\n            \"bbsmo.com\",\n            \"bbsone.com\",\n            \"bbtoystore.com\",\n            \"bcast.co.nz\",\n            \"bcc.com.tw\",\n            \"bcchinese.net\",\n            \"bcex.ca\",\n            \"bcmorning.com\",\n            \"bdsmvideos.net\",\n            \"beaconevents.com\",\n            \"bebo.com\",\n            \"beeg.com\",\n            \"beevpn.com\",\n            \"behance.net\",\n            \"behindkink.com\",\n            \"beijing1989.com\",\n            \"beijing2022.art\",\n            \"beijingspring.com\",\n            \"beijingzx.org\",\n            \"belamionline.com\",\n            \"bell.wiki\",\n            \"bemywife.cc\",\n            \"beric.me\",\n            \"berlinerbericht.de\",\n            \"berlintwitterwall.com\",\n            \"berm.co.nz\",\n            \"bestforchina.org\",\n            \"bestgore.com\",\n            \"bestpornstardb.com\",\n            \"bestvpn.com\",\n            \"bestvpnanalysis.com\",\n            \"bestvpnserver.com\",\n            \"bestvpnservice.com\",\n            \"bestvpnusa.com\",\n            \"bet365.com\",\n            \"betfair.com\",\n            \"betternet.co\",\n            \"bettervpn.com\",\n            \"bettween.com\",\n            \"betvictor.com\",\n            \"bewww.net\",\n            \"beyondfirewall.com\",\n            \"bfnn.org\",\n            \"bfsh.hk\",\n            \"bgvpn.com\",\n            \"bianlei.com\",\n            \"biantailajiao.com\",\n            \"biantailajiao.in\",\n            \"biblesforamerica.org\",\n            \"bibox.com\",\n            \"bic2011.org\",\n            \"biedian.me\",\n            \"big.one\",\n            \"bigfools.com\",\n            \"bigjapanesesex.com\",\n            \"bigmoney.biz\",\n            \"bignews.org\",\n            \"bigone.com\",\n            \"bigsound.org\",\n            \"bild.de\",\n            \"biliworld.com\",\n            \"billypan.com\",\n            \"binance.com\",\n            \"bing.com\",\n            \"binux.me\",\n            \"binwang.me\",\n            \"bird.so\",\n            \"bit-z.com\",\n            \"bit.do\",\n            \"bit.ly\",\n            \"bitbay.net\",\n            \"bitchute.com\",\n            \"bitcointalk.org\",\n            \"bitcoinworld.com\",\n            \"bitfinex.com\",\n            \"bithumb.com\",\n            \"bitinka.com.ar\",\n            \"bitmex.com\",\n            \"bitshare.com\",\n            \"bitsnoop.com\",\n            \"bitterwinter.org\",\n            \"bitvise.com\",\n            \"bitz.ai\",\n            \"bizhat.com\",\n            \"bjnewlife.org\",\n            \"bjs.org\",\n            \"bjzc.org\",\n            \"bl-doujinsouko.com\",\n            \"blacklogic.com\",\n            \"blackvpn.com\",\n            \"blewpass.com\",\n            \"blingblingsquad.net\",\n            \"blinkx.com\",\n            \"blinw.com\",\n            \"blip.tv\",\n            \"blockcast.it\",\n            \"blockcn.com\",\n            \"blockedbyhk.com\",\n            \"blockless.com\",\n            \"blog.de\",\n            \"blog.google\",\n            \"blog.jp\",\n            \"blogblog.com\",\n            \"blogcatalog.com\",\n            \"blogcity.me\",\n            \"blogdns.org\",\n            \"blogger.com\",\n            \"blogimg.jp\",\n            \"bloglines.com\",\n            \"bloglovin.com\",\n            \"blogs.com\",\n            \"blogspot.com\",\n            \"blogspot.hk\",\n            \"blogspot.jp\",\n            \"blogspot.tw\",\n            \"blogtd.net\",\n            \"blogtd.org\",\n            \"bloodshed.net\",\n            \"bloomberg.cn\",\n            \"bloomberg.com\",\n            \"bloomberg.de\",\n            \"bloombergview.com\",\n            \"bloomfortune.com\",\n            \"blubrry.com\",\n            \"blueangellive.com\",\n            \"bmfinn.com\",\n            \"bnews.co\",\n            \"bnext.com.tw\",\n            \"bnn.co\",\n            \"bnrmetal.com\",\n            \"boardreader.com\",\n            \"bod.asia\",\n            \"bodog88.com\",\n            \"bolehvpn.net\",\n            \"bonbonme.com\",\n            \"bonbonsex.com\",\n            \"bonfoundation.org\",\n            \"bongacams.com\",\n            \"boobstagram.com\",\n            \"book.com.tw\",\n            \"bookdepository.com\",\n            \"bookepub.com\",\n            \"books.com.tw\",\n            \"booktopia.com.au\",\n            \"boomssr.com\",\n            \"borgenmagazine.com\",\n            \"bot.nu\",\n            \"botanwang.com\",\n            \"bowenpress.com\",\n            \"box.com\",\n            \"box.net\",\n            \"boxpn.com\",\n            \"boxun.com\",\n            \"boxun.tv\",\n            \"boxunblog.com\",\n            \"boxunclub.com\",\n            \"boyangu.com\",\n            \"boyfriendtv.com\",\n            \"boysfood.com\",\n            \"boysmaster.com\",\n            \"br.st\",\n            \"brainyquote.com\",\n            \"brandonhutchinson.com\",\n            \"braumeister.org\",\n            \"brave.com\",\n            \"bravotube.net\",\n            \"brazzers.com\",\n            \"breached.to\",\n            \"break.com\",\n            \"breakgfw.com\",\n            \"breaking911.com\",\n            \"breakingtweets.com\",\n            \"breakwall.net\",\n            \"briefdream.com\",\n            \"briian.com\",\n            \"brill.com\",\n            \"brizzly.com\",\n            \"brkmd.com\",\n            \"broadbook.com\",\n            \"broadpressinc.com\",\n            \"brockbbs.com\",\n            \"brookings.edu\",\n            \"brucewang.net\",\n            \"brutaltgp.com\",\n            \"bt2mag.com\",\n            \"bt95.com\",\n            \"btaia.com\",\n            \"btbtav.com\",\n            \"btc98.com\",\n            \"btcbank.bank\",\n            \"btctrade.im\",\n            \"btdigg.org\",\n            \"btku.me\",\n            \"btku.org\",\n            \"btspread.com\",\n            \"btsynckeys.com\",\n            \"budaedu.org\",\n            \"buddhanet.com.tw\",\n            \"buddhistchannel.tv\",\n            \"buffered.com\",\n            \"bullguard.com\",\n            \"bullog.org\",\n            \"bullogger.com\",\n            \"bunbunhk.com\",\n            \"busayari.com\",\n            \"business-humanrights.org\",\n            \"business.page\",\n            \"businessinsider.com\",\n            \"businessinsider.com.au\",\n            \"businesstoday.com.tw\",\n            \"businessweek.com\",\n            \"busu.org\",\n            \"busytrade.com\",\n            \"buugaa.com\",\n            \"buzzhand.com\",\n            \"buzzhand.net\",\n            \"buzzorange.com\",\n            \"bvpn.com\",\n            \"bwbx.io\",\n            \"bwgyhw.com\",\n            \"bwh1.net\",\n            \"bwsj.hk\",\n            \"bx.in.th\",\n            \"bx.tl\",\n            \"bybit.com\",\n            \"bynet.co.il\",\n            \"bypasscensorship.org\",\n            \"byrut.org\",\n            \"c-est-simple.com\",\n            \"c-span.org\",\n            \"c-spanvideo.org\",\n            \"c100tibet.org\",\n            \"c2cx.com\",\n            \"cablegatesearch.net\",\n            \"cachinese.com\",\n            \"cacnw.com\",\n            \"cactusvpn.com\",\n            \"cafepress.com\",\n            \"cahr.org.tw\",\n            \"caijinglengyan.com\",\n            \"calameo.com\",\n            \"calebelston.com\",\n            \"calgarychinese.ca\",\n            \"calgarychinese.com\",\n            \"calgarychinese.net\",\n            \"calibre-ebook.com\",\n            \"caltech.edu\",\n            \"cam4.com\",\n            \"cam4.jp\",\n            \"cam4.sg\",\n            \"camfrog.com\",\n            \"campaignforuyghurs.org\",\n            \"cams.com\",\n            \"cams.org.sg\",\n            \"canadameet.com\",\n            \"canalporno.com\",\n            \"cantonese.asia\",\n            \"canyu.org\",\n            \"cao.im\",\n            \"caobian.info\",\n            \"caochangqing.com\",\n            \"cap.org.hk\",\n            \"carabinasypistolas.com\",\n            \"cardinalkungfoundation.org\",\n            \"careerengine.us\",\n            \"carfax.com\",\n            \"cari.com.my\",\n            \"caribbeancom.com\",\n            \"carmotorshow.com\",\n            \"carrd.co\",\n            \"carryzhou.com\",\n            \"cartoonmovement.com\",\n            \"casadeltibetbcn.org\",\n            \"casatibet.org.mx\",\n            \"casinobellini.com\",\n            \"casinoking.com\",\n            \"casinoriva.com\",\n            \"castbox.fm\",\n            \"catch22.net\",\n            \"catchgod.com\",\n            \"catfightpayperview.xxx\",\n            \"catholic.org.hk\",\n            \"catholic.org.tw\",\n            \"cathvoice.org.tw\",\n            \"cato.org\",\n            \"cattt.com\",\n            \"cbc.ca\",\n            \"cbsnews.com\",\n            \"cbtc.org.hk\",\n            \"cc.com\",\n            \"cccat.cc\",\n            \"cccat.co\",\n            \"ccdtr.org\",\n            \"cchere.com\",\n            \"ccim.org\",\n            \"cclife.ca\",\n            \"cclife.org\",\n            \"cclifefl.org\",\n            \"ccthere.com\",\n            \"ccthere.net\",\n            \"cctmweb.net\",\n            \"cctongbao.com\",\n            \"ccue.ca\",\n            \"ccue.com\",\n            \"ccvoice.ca\",\n            \"ccw.org.tw\",\n            \"cdbook.org\",\n            \"cdcparty.com\",\n            \"cdef.org\",\n            \"cdig.info\",\n            \"cdjp.org\",\n            \"cdnews.com.tw\",\n            \"cdninstagram.com\",\n            \"cdp1989.org\",\n            \"cdp1998.org\",\n            \"cdp2006.org\",\n            \"cdpeu.org\",\n            \"cdpusa.org\",\n            \"cdpweb.org\",\n            \"cdpwu.org\",\n            \"cdw.com\",\n            \"cecc.gov\",\n            \"cellulo.info\",\n            \"cenews.eu\",\n            \"centauro.com.br\",\n            \"centerforhumanreprod.com\",\n            \"centralnation.com\",\n            \"centurys.net\",\n            \"certificate-transparency.org\",\n            \"cfhks.org.hk\",\n            \"cfos.de\",\n            \"cfr.org\",\n            \"cftfc.com\",\n            \"cgdepot.org\",\n            \"cgst.edu\",\n            \"change.org\",\n            \"changeip.name\",\n            \"changeip.net\",\n            \"changeip.org\",\n            \"changp.com\",\n            \"changsa.net\",\n            \"channelnewsasia.com\",\n            \"chaoex.com\",\n            \"chapm25.com\",\n            \"chatnook.com\",\n            \"chaturbate.com\",\n            \"checkgfw.com\",\n            \"chengmingmag.com\",\n            \"chenguangcheng.com\",\n            \"chenpokong.com\",\n            \"chenpokong.net\",\n            \"chenpokongvip.com\",\n            \"cherrysave.com\",\n            \"chhongbi.org\",\n            \"chicagoncmtv.com\",\n            \"china-mmm.net\",\n            \"china-review.com.ua\",\n            \"china-week.com\",\n            \"china101.com\",\n            \"china18.org\",\n            \"china21.com\",\n            \"china21.org\",\n            \"china5000.us\",\n            \"chinaaffairs.org\",\n            \"chinaaid.me\",\n            \"chinaaid.net\",\n            \"chinaaid.org\",\n            \"chinaaid.us\",\n            \"chinachange.org\",\n            \"chinachannel.hk\",\n            \"chinacitynews.be\",\n            \"chinacomments.org\",\n            \"chinadialogue.net\",\n            \"chinadigitaltimes.net\",\n            \"chinaelections.org\",\n            \"chinaeweekly.com\",\n            \"chinafreepress.org\",\n            \"chinagate.com\",\n            \"chinageeks.org\",\n            \"chinagfw.org\",\n            \"chinagonet.com\",\n            \"chinagreenparty.org\",\n            \"chinahorizon.org\",\n            \"chinahush.com\",\n            \"chinainperspective.com\",\n            \"chinainterimgov.org\",\n            \"chinalaborwatch.org\",\n            \"chinalawandpolicy.com\",\n            \"chinalawtranslate.com\",\n            \"chinamule.com\",\n            \"chinamz.org\",\n            \"chinanewscenter.com\",\n            \"chinapost.com.tw\",\n            \"chinapress.com.my\",\n            \"chinarightsia.org\",\n            \"chinasmile.net\",\n            \"chinasocialdemocraticparty.com\",\n            \"chinasoul.org\",\n            \"chinasucks.net\",\n            \"chinatimes.com\",\n            \"chinatopsex.com\",\n            \"chinatown.com.au\",\n            \"chinatweeps.com\",\n            \"chinaway.org\",\n            \"chinaworker.info\",\n            \"chinaxchina.com\",\n            \"chinayouth.org.hk\",\n            \"chinayuanmin.org\",\n            \"chinese-hermit.net\",\n            \"chinese-leaders.org\",\n            \"chinese-memorial.org\",\n            \"chinesedaily.com\",\n            \"chinesedailynews.com\",\n            \"chinesedemocracy.com\",\n            \"chinesegay.org\",\n            \"chinesen.de\",\n            \"chinesenews.net.au\",\n            \"chinesepen.org\",\n            \"chineseradioseattle.com\",\n            \"chinesetalks.net\",\n            \"chineseupress.com\",\n            \"chingcheong.com\",\n            \"chinman.net\",\n            \"chithu.org\",\n            \"chobit.cc\",\n            \"chosun.com\",\n            \"chrdnet.com\",\n            \"christianfreedom.org\",\n            \"christianstudy.com\",\n            \"christiantimes.org.hk\",\n            \"christusrex.org\",\n            \"chrlawyers.hk\",\n            \"chrome.com\",\n            \"chromecast.com\",\n            \"chromeenterprise.google\",\n            \"chromeexperiments.com\",\n            \"chromercise.com\",\n            \"chromestatus.com\",\n            \"chromium.org\",\n            \"chuang-yen.org\",\n            \"chubold.com\",\n            \"chubun.com\",\n            \"churchinhongkong.org\",\n            \"chushigangdrug.ch\",\n            \"cienen.com\",\n            \"cineastentreff.de\",\n            \"cipfg.org\",\n            \"circlethebayfortibet.org\",\n            \"cirosantilli.com\",\n            \"citizencn.com\",\n            \"citizenlab.ca\",\n            \"citizenlab.org\",\n            \"citizenscommission.hk\",\n            \"citizensradio.org\",\n            \"city365.ca\",\n            \"city9x.com\",\n            \"citypopulation.de\",\n            \"citytalk.tw\",\n            \"civicparty.hk\",\n            \"civildisobediencemovement.org\",\n            \"civilhrfront.org\",\n            \"civiliangunner.com\",\n            \"civilmedia.tw\",\n            \"civisec.org\",\n            \"cjb.net\",\n            \"ck101.com\",\n            \"clarionproject.org\",\n            \"classicalguitarblog.net\",\n            \"clb.org.hk\",\n            \"cleansite.biz\",\n            \"cleansite.info\",\n            \"cleansite.us\",\n            \"clearharmony.net\",\n            \"clearsurance.com\",\n            \"clearwisdom.net\",\n            \"clementine-player.org\",\n            \"clinica-tibet.ru\",\n            \"clipfish.de\",\n            \"cloakpoint.com\",\n            \"cloudcone.com\",\n            \"cloudflare-ipfs.com\",\n            \"cloudfront.net\",\n            \"club1069.com\",\n            \"clubhouseapi.com\",\n            \"clyp.it\",\n            \"cmcn.org\",\n            \"cmi.org.tw\",\n            \"cmoinc.org\",\n            \"cms.gov\",\n            \"cmu.edu\",\n            \"cmule.com\",\n            \"cmule.org\",\n            \"cmx.im\",\n            \"cn-proxy.com\",\n            \"cn.com\",\n            \"cn6.eu\",\n            \"cna.com.tw\",\n            \"cnabc.com\",\n            \"cnd.org\",\n            \"cnet.com\",\n            \"cnex.org.cn\",\n            \"cnineu.com\",\n            \"cnitter.com\",\n            \"cnn.com\",\n            \"cnpolitics.org\",\n            \"cnproxy.com\",\n            \"cnyes.com\",\n            \"co.tv\",\n            \"coat.co.jp\",\n            \"cobinhood.com\",\n            \"cochina.co\",\n            \"cochina.org\",\n            \"code1984.com\",\n            \"codeplex.com\",\n            \"codeshare.io\",\n            \"codeskulptor.org\",\n            \"coin2co.in\",\n            \"coinbene.com\",\n            \"coinegg.com\",\n            \"coinex.com\",\n            \"coingecko.com\",\n            \"coingi.com\",\n            \"coinmarketcap.com\",\n            \"coinrail.co.kr\",\n            \"cointiger.com\",\n            \"cointobe.com\",\n            \"coinut.com\",\n            \"collateralmurder.com\",\n            \"collateralmurder.org\",\n            \"com.google\",\n            \"com.ru\",\n            \"com.uk\",\n            \"comedycentral.com\",\n            \"comefromchina.com\",\n            \"comic-mega.me\",\n            \"comico.tw\",\n            \"commandarms.com\",\n            \"commentshk.com\",\n            \"communistcrimes.org\",\n            \"communitychoicecu.com\",\n            \"comparitech.com\",\n            \"compileheart.com\",\n            \"compress.to\",\n            \"compython.net\",\n            \"conoha.jp\",\n            \"constitutionalism.solutions\",\n            \"contactmagazine.net\",\n            \"convio.net\",\n            \"coobay.com\",\n            \"cool18.com\",\n            \"coolaler.com\",\n            \"coolder.com\",\n            \"coolloud.org.tw\",\n            \"coolncute.com\",\n            \"coolstuffinc.com\",\n            \"corumcollege.com\",\n            \"cos-moe.com\",\n            \"cosplayjav.pl\",\n            \"costco.com\",\n            \"cotweet.com\",\n            \"counter.social\",\n            \"coursehero.com\",\n            \"cpj.org\",\n            \"cq99.us\",\n            \"crackle.com\",\n            \"crazys.cc\",\n            \"crazyshit.com\",\n            \"crbug.com\",\n            \"crchina.org\",\n            \"crd-net.org\",\n            \"creaders.net\",\n            \"creadersnet.com\",\n            \"creativelab5.com\",\n            \"crisisresponse.google\",\n            \"cristyli.com\",\n            \"crocotube.com\",\n            \"crossfire.co.kr\",\n            \"crossthewall.net\",\n            \"crossvpn.net\",\n            \"croxyproxy.com\",\n            \"crrev.com\",\n            \"crucial.com\",\n            \"crunchyroll.com\",\n            \"cryptographyengineering.com\",\n            \"csdparty.com\",\n            \"csis.org\",\n            \"csmonitor.com\",\n            \"csuchen.de\",\n            \"csw.org.uk\",\n            \"ct.org.tw\",\n            \"ctao.org\",\n            \"ctfriend.net\",\n            \"ctitv.com.tw\",\n            \"ctowc.org\",\n            \"cts.com.tw\",\n            \"ctwant.com\",\n            \"cuhk.edu.hk\",\n            \"cuhkacs.org\",\n            \"cuihua.org\",\n            \"cuiweiping.net\",\n            \"culture.tw\",\n            \"cumlouder.com\",\n            \"curvefish.com\",\n            \"cusp.hk\",\n            \"cusu.hk\",\n            \"cutscenes.net\",\n            \"cw.com.tw\",\n            \"cwb.gov.tw\",\n            \"cyberctm.com\",\n            \"cyberghostvpn.com\",\n            \"cynscribe.com\",\n            \"cytode.us\",\n            \"cz.cc\",\n            \"d-fukyu.com\",\n            \"d0z.net\",\n            \"d100.net\",\n            \"d2bay.com\",\n            \"d2pass.com\",\n            \"dabr.co.uk\",\n            \"dabr.eu\",\n            \"dabr.me\",\n            \"dabr.mobi\",\n            \"dadazim.com\",\n            \"dadi360.com\",\n            \"dafabet.com\",\n            \"dafagood.com\",\n            \"dafahao.com\",\n            \"dafoh.org\",\n            \"daftporn.com\",\n            \"dagelijksestandaard.nl\",\n            \"daidostup.ru\",\n            \"dailidaili.com\",\n            \"dailymail.co.uk\",\n            \"dailymotion.com\",\n            \"dailysabah.com\",\n            \"dailyview.tw\",\n            \"daiphapinfo.net\",\n            \"dajiyuan.com\",\n            \"dajiyuan.de\",\n            \"dajiyuan.eu\",\n            \"dalailama-archives.org\",\n            \"dalailama.com\",\n            \"dalailama.mn\",\n            \"dalailama.ru\",\n            \"dalailama80.org\",\n            \"dalailamacenter.org\",\n            \"dalailamafellows.org\",\n            \"dalailamafilm.com\",\n            \"dalailamafoundation.org\",\n            \"dalailamahindi.com\",\n            \"dalailamainaustralia.org\",\n            \"dalailamajapanese.com\",\n            \"dalailamaprotesters.info\",\n            \"dalailamaquotes.org\",\n            \"dalailamatrust.org\",\n            \"dalailamavisit.org.nz\",\n            \"dalailamaworld.com\",\n            \"dalianmeng.org\",\n            \"daliulian.org\",\n            \"danke4china.net\",\n            \"daolan.net\",\n            \"darktech.org\",\n            \"darktoy.net\",\n            \"darpa.mil\",\n            \"darrenliuwei.com\",\n            \"dastrassi.org\",\n            \"data-vocabulary.org\",\n            \"data.gov.tw\",\n            \"daum.net\",\n            \"david-kilgour.com\",\n            \"dawangidc.com\",\n            \"daxa.cn\",\n            \"dayabook.com\",\n            \"daylife.com\",\n            \"db.tt\",\n            \"dbc.hk\",\n            \"dbgjd.com\",\n            \"dcard.tw\",\n            \"dcmilitary.com\",\n            \"ddc.com.tw\",\n            \"ddhw.info\",\n            \"ddns.info\",\n            \"ddns.me.uk\",\n            \"ddns.mobi\",\n            \"ddns.ms\",\n            \"ddns.name\",\n            \"ddns.net\",\n            \"ddns.us\",\n            \"de-sci.org\",\n            \"deadline.com\",\n            \"deaftone.com\",\n            \"debug.com\",\n            \"deck.ly\",\n            \"decodet.co\",\n            \"deepmind.com\",\n            \"deezer.com\",\n            \"definebabe.com\",\n            \"deja.com\",\n            \"delcamp.net\",\n            \"delicious.com\",\n            \"democrats.org\",\n            \"demosisto.hk\",\n            \"depositphotos.com\",\n            \"desc.se\",\n            \"design.google\",\n            \"desipro.de\",\n            \"dessci.com\",\n            \"destroy-china.jp\",\n            \"deutsche-welle.de\",\n            \"deviantart.com\",\n            \"deviantart.net\",\n            \"devio.us\",\n            \"devpn.com\",\n            \"dfas.mil\",\n            \"dfn.org\",\n            \"dharamsalanet.com\",\n            \"dharmakara.net\",\n            \"dhcp.biz\",\n            \"diaoyuislands.org\",\n            \"difangwenge.org\",\n            \"digiland.tw\",\n            \"digisfera.com\",\n            \"digitalnomadsproject.org\",\n            \"diigo.com\",\n            \"dilber.se\",\n            \"dingchin.com.tw\",\n            \"dipity.com\",\n            \"directcreative.com\",\n            \"discoins.com\",\n            \"disconnect.me\",\n            \"discord.com\",\n            \"discord.gg\",\n            \"discordapp.com\",\n            \"discordapp.net\",\n            \"discuss.com.hk\",\n            \"discuss4u.com\",\n            \"dish.com\",\n            \"disp.cc\",\n            \"disqus.com\",\n            \"dit-inc.us\",\n            \"dizhidizhi.com\",\n            \"dizhuzhishang.com\",\n            \"djangosnippets.org\",\n            \"djorz.com\",\n            \"dl-laby.jp\",\n            \"dlive.tv\",\n            \"dlsite.com\",\n            \"dlsite.jp\",\n            \"dlyoutube.com\",\n            \"dm530.net\",\n            \"dmc.nico\",\n            \"dmcdn.net\",\n            \"dmhy.org\",\n            \"dmm.co.jp\",\n            \"dmm.com\",\n            \"dns-dns.com\",\n            \"dns-stuff.com\",\n            \"dns.google\",\n            \"dns04.com\",\n            \"dns05.com\",\n            \"dns1.us\",\n            \"dns2.us\",\n            \"dns2go.com\",\n            \"dnscrypt.org\",\n            \"dnset.com\",\n            \"dnsrd.com\",\n            \"dnssec.net\",\n            \"dnvod.tv\",\n            \"doctorvoice.org\",\n            \"documentingreality.com\",\n            \"dogfartnetwork.com\",\n            \"dojin.com\",\n            \"dok-forum.net\",\n            \"dolc.de\",\n            \"dolf.org.hk\",\n            \"dollf.com\",\n            \"domain.club.tw\",\n            \"domains.google\",\n            \"domaintoday.com.au\",\n            \"donga.com\",\n            \"dongtaiwang.com\",\n            \"dongtaiwang.net\",\n            \"dongyangjing.com\",\n            \"donmai.us\",\n            \"dontfilter.us\",\n            \"dontmovetochina.com\",\n            \"dorjeshugden.com\",\n            \"dotplane.com\",\n            \"dotsub.com\",\n            \"dotvpn.com\",\n            \"doub.io\",\n            \"doubibackup.com\",\n            \"doubmirror.cf\",\n            \"dougscripts.com\",\n            \"douhokanko.net\",\n            \"doujincafe.com\",\n            \"dowei.org\",\n            \"dowjones.com\",\n            \"dphk.org\",\n            \"dpp.org.tw\",\n            \"dpr.info\",\n            \"dragonex.io\",\n            \"dragonsprings.org\",\n            \"dreamamateurs.com\",\n            \"drepung.org\",\n            \"drgan.net\",\n            \"drmingxia.org\",\n            \"dropbooks.tv\",\n            \"dropbox.com\",\n            \"dropboxapi.com\",\n            \"dropboxusercontent.com\",\n            \"drsunacademy.com\",\n            \"drtuber.com\",\n            \"dscn.info\",\n            \"dsmtp.com\",\n            \"dstk.dk\",\n            \"dtdns.net\",\n            \"dtiblog.com\",\n            \"dtic.mil\",\n            \"dtwang.org\",\n            \"duanzhihu.com\",\n            \"dubox.com\",\n            \"duck.com\",\n            \"duckdns.org\",\n            \"duckduckgo.com\",\n            \"duckload.com\",\n            \"duckmylife.com\",\n            \"duga.jp\",\n            \"duihua.org\",\n            \"duihuahrjournal.org\",\n            \"dumb1.com\",\n            \"dunyabulteni.net\",\n            \"duoweitimes.com\",\n            \"duping.net\",\n            \"duplicati.com\",\n            \"dupola.com\",\n            \"dupola.net\",\n            \"dushi.ca\",\n            \"duyaoss.com\",\n            \"dvdpac.com\",\n            \"dvorak.org\",\n            \"dw-world.com\",\n            \"dw-world.de\",\n            \"dw.com\",\n            \"dw.de\",\n            \"dwheeler.com\",\n            \"dwnews.com\",\n            \"dwnews.net\",\n            \"dxiong.com\",\n            \"dynamic-dns.net\",\n            \"dynamicdns.biz\",\n            \"dynamicdns.co.uk\",\n            \"dynamicdns.me.uk\",\n            \"dynamicdns.org.uk\",\n            \"dynawebinc.com\",\n            \"dyndns-ip.com\",\n            \"dyndns-pics.com\",\n            \"dyndns.org\",\n            \"dyndns.pro\",\n            \"dynssl.com\",\n            \"dynu.com\",\n            \"dynu.net\",\n            \"dysfz.cc\",\n            \"dzze.com\",\n            \"e-classical.com.tw\",\n            \"e-gold.com\",\n            \"e-hentai.org\",\n            \"e-hentaidb.com\",\n            \"e-info.org.tw\",\n            \"e-traderland.net\",\n            \"e-zone.com.hk\",\n            \"e123.hk\",\n            \"earlytibet.com\",\n            \"earthcam.com\",\n            \"earthvpn.com\",\n            \"eastern-ark.com\",\n            \"easternlightning.org\",\n            \"eastturkestan.com\",\n            \"eastturkistan-gov.org\",\n            \"eastturkistan.net\",\n            \"eastturkistancc.org\",\n            \"eastturkistangovernmentinexile.us\",\n            \"easyca.ca\",\n            \"easypic.com\",\n            \"ebc.net.tw\",\n            \"ebony-beauty.com\",\n            \"ebookbrowse.com\",\n            \"ebookee.com\",\n            \"ebtcbank.com\",\n            \"ecfa.org.tw\",\n            \"echainhost.com\",\n            \"echofon.com\",\n            \"ecimg.tw\",\n            \"ecministry.net\",\n            \"economist.com\",\n            \"ecstart.com\",\n            \"edgecastcdn.net\",\n            \"edgesuite.net\",\n            \"edicypages.com\",\n            \"edmontonchina.cn\",\n            \"edmontonservice.com\",\n            \"edns.biz\",\n            \"edoors.com\",\n            \"edubridge.com\",\n            \"edupro.org\",\n            \"eesti.ee\",\n            \"eevpn.com\",\n            \"efcc.org.hk\",\n            \"effers.com\",\n            \"efksoft.com\",\n            \"efukt.com\",\n            \"eic-av.com\",\n            \"eireinikotaerukai.com\",\n            \"eisbb.com\",\n            \"eksisozluk.com\",\n            \"electionsmeter.com\",\n            \"elgoog.im\",\n            \"ellawine.org\",\n            \"elpais.com\",\n            \"eltondisney.com\",\n            \"emaga.com\",\n            \"emanna.com\",\n            \"emilylau.org.hk\",\n            \"emory.edu\",\n            \"empfil.com\",\n            \"emule-ed2k.com\",\n            \"emulefans.com\",\n            \"emuparadise.me\",\n            \"enanyang.my\",\n            \"encrypt.me\",\n            \"encyclopedia.com\",\n            \"enewstree.com\",\n            \"enfal.de\",\n            \"engadget.com\",\n            \"engagedaily.org\",\n            \"englishforeveryone.org\",\n            \"englishfromengland.co.uk\",\n            \"englishpen.org\",\n            \"enlighten.org.tw\",\n            \"entermap.com\",\n            \"environment.google\",\n            \"epa.gov.tw\",\n            \"epac.to\",\n            \"episcopalchurch.org\",\n            \"epochhk.com\",\n            \"epochtimes-bg.com\",\n            \"epochtimes-romania.com\",\n            \"epochtimes.co.il\",\n            \"epochtimes.co.kr\",\n            \"epochtimes.com\",\n            \"epochtimes.cz\",\n            \"epochtimes.de\",\n            \"epochtimes.fr\",\n            \"epochtimes.ie\",\n            \"epochtimes.it\",\n            \"epochtimes.jp\",\n            \"epochtimes.ru\",\n            \"epochtimes.se\",\n            \"epochtimestr.com\",\n            \"epochweek.com\",\n            \"epochweekly.com\",\n            \"eporner.com\",\n            \"equinenow.com\",\n            \"erabaru.net\",\n            \"eracom.com.tw\",\n            \"eraysoft.com.tr\",\n            \"erepublik.com\",\n            \"erights.net\",\n            \"eriversoft.com\",\n            \"erktv.com\",\n            \"ernestmandel.org\",\n            \"erodaizensyu.com\",\n            \"erodoujinlog.com\",\n            \"erodoujinworld.com\",\n            \"eromanga-kingdom.com\",\n            \"eromangadouzin.com\",\n            \"eromon.net\",\n            \"eroprofile.com\",\n            \"eroticsaloon.net\",\n            \"eslite.com\",\n            \"esmtp.biz\",\n            \"esu.dog\",\n            \"esu.im\",\n            \"esurance.com\",\n            \"etaa.org.au\",\n            \"etadult.com\",\n            \"etaiwannews.com\",\n            \"etherdelta.com\",\n            \"etherscan.io\",\n            \"etizer.org\",\n            \"etokki.com\",\n            \"etowns.net\",\n            \"etowns.org\",\n            \"etsy.com\",\n            \"ettoday.net\",\n            \"etvonline.hk\",\n            \"eu.org\",\n            \"eucasino.com\",\n            \"eulam.com\",\n            \"eurekavpt.com\",\n            \"euronews.com\",\n            \"europa.eu\",\n            \"evozi.com\",\n            \"evschool.net\",\n            \"exblog.co.jp\",\n            \"exblog.jp\",\n            \"exchristian.hk\",\n            \"excite.co.jp\",\n            \"exhentai.org\",\n            \"exmo.com\",\n            \"exmormon.org\",\n            \"expatshield.com\",\n            \"expecthim.com\",\n            \"expekt.com\",\n            \"experts-univers.com\",\n            \"exploader.net\",\n            \"expofutures.com\",\n            \"expressvpn.com\",\n            \"exrates.me\",\n            \"extmatrix.com\",\n            \"extremetube.com\",\n            \"exx.com\",\n            \"eyevio.jp\",\n            \"eyny.com\",\n            \"ezpc.tk\",\n            \"ezpeer.com\",\n            \"ezua.com\",\n            \"f8.com\",\n            \"fa.gov.tw\",\n            \"facebook.br\",\n            \"facebook.com\",\n            \"facebook.design\",\n            \"facebook.hu\",\n            \"facebook.in\",\n            \"facebook.net\",\n            \"facebook.nl\",\n            \"facebook.se\",\n            \"facebookmail.com\",\n            \"facebookquotes4u.com\",\n            \"faceless.me\",\n            \"facesofnyfw.com\",\n            \"facesoftibetanselfimmolators.info\",\n            \"factpedia.org\",\n            \"fail.hk\",\n            \"faith100.org\",\n            \"faithfuleye.com\",\n            \"faiththedog.info\",\n            \"fakku.net\",\n            \"fallenark.com\",\n            \"falsefire.com\",\n            \"falun-co.org\",\n            \"falun-ny.net\",\n            \"falunart.org\",\n            \"falunasia.info\",\n            \"falunau.org\",\n            \"falunaz.net\",\n            \"falundafa-dc.org\",\n            \"falundafa-florida.org\",\n            \"falundafa-nc.org\",\n            \"falundafa-pa.net\",\n            \"falundafa-sacramento.org\",\n            \"falundafa.org\",\n            \"falundafaindia.org\",\n            \"falundafamuseum.org\",\n            \"falungong.club\",\n            \"falungong.de\",\n            \"falungong.org.uk\",\n            \"falunhr.org\",\n            \"faluninfo.de\",\n            \"faluninfo.net\",\n            \"falunpilipinas.net\",\n            \"falunworld.net\",\n            \"familyfed.org\",\n            \"famunion.com\",\n            \"fan-qiang.com\",\n            \"fandom.com\",\n            \"fangbinxing.com\",\n            \"fangeming.com\",\n            \"fangeqiang.com\",\n            \"fanglizhi.info\",\n            \"fangmincn.org\",\n            \"fangong.org\",\n            \"fangongheike.com\",\n            \"fanhaodang.com\",\n            \"fanhaolou.com\",\n            \"fanqiang.network\",\n            \"fanqiang.tk\",\n            \"fanqiangdang.com\",\n            \"fanqianghou.com\",\n            \"fanqiangyakexi.net\",\n            \"fanqiangzhe.com\",\n            \"fanswong.com\",\n            \"fantv.hk\",\n            \"fanyue.info\",\n            \"fapdu.com\",\n            \"faproxy.com\",\n            \"faqserv.com\",\n            \"fartit.com\",\n            \"farwestchina.com\",\n            \"fastestvpn.com\",\n            \"fastly.net\",\n            \"fastpic.ru\",\n            \"fastssh.com\",\n            \"faststone.org\",\n            \"fatbtc.com\",\n            \"favotter.net\",\n            \"favstar.fm\",\n            \"fawanghuihui.org\",\n            \"faydao.com\",\n            \"faz.net\",\n            \"fb.com\",\n            \"fb.me\",\n            \"fb.watch\",\n            \"fbaddins.com\",\n            \"fbcdn.net\",\n            \"fbsbx.com\",\n            \"fbworkmail.com\",\n            \"fc2.com\",\n            \"fc2blog.net\",\n            \"fc2china.com\",\n            \"fc2cn.com\",\n            \"fc2web.com\",\n            \"fda.gov.tw\",\n            \"fdbox.com\",\n            \"fdc64.de\",\n            \"fdc64.org\",\n            \"fdc89.jp\",\n            \"feedburner.com\",\n            \"feeder.co\",\n            \"feedly.com\",\n            \"feedx.net\",\n            \"feelssh.com\",\n            \"feer.com\",\n            \"feifeiss.com\",\n            \"feitian-california.org\",\n            \"feitianacademy.org\",\n            \"feixiaohao.com\",\n            \"feministteacher.com\",\n            \"fengzhenghu.com\",\n            \"fengzhenghu.net\",\n            \"fevernet.com\",\n            \"ff.im\",\n            \"fffff.at\",\n            \"fflick.com\",\n            \"ffvpn.com\",\n            \"fgmtv.net\",\n            \"fgmtv.org\",\n            \"fhreports.net\",\n            \"figprayer.com\",\n            \"fileflyer.com\",\n            \"fileforum.com\",\n            \"files2me.com\",\n            \"fileserve.com\",\n            \"filesor.com\",\n            \"fillthesquare.org\",\n            \"filmingfortibet.org\",\n            \"filthdump.com\",\n            \"financetwitter.com\",\n            \"finchvpn.com\",\n            \"findmespot.com\",\n            \"findyoutube.com\",\n            \"findyoutube.net\",\n            \"fingerdaily.com\",\n            \"finler.net\",\n            \"firearmsworld.net\",\n            \"firebaseio.com\",\n            \"firefox.com\",\n            \"fireofliberty.org\",\n            \"firetweet.io\",\n            \"firstfivefollowers.com\",\n            \"firstpost.com\",\n            \"firstrade.com\",\n            \"fizzik.com\",\n            \"flagsonline.it\",\n            \"flecheinthepeche.fr\",\n            \"fleshbot.com\",\n            \"fleursdeslettres.com\",\n            \"flgg.us\",\n            \"flgjustice.org\",\n            \"flickr.com\",\n            \"flickrhivemind.net\",\n            \"flickriver.com\",\n            \"fling.com\",\n            \"flipboard.com\",\n            \"flipkart.com\",\n            \"flitto.com\",\n            \"flnet.org\",\n            \"flog.tw\",\n            \"flurry.com\",\n            \"flyvpn.com\",\n            \"flyzy2005.com\",\n            \"fmnnow.com\",\n            \"fnac.be\",\n            \"fnac.com\",\n            \"fochk.org\",\n            \"focustaiwan.tw\",\n            \"focusvpn.com\",\n            \"fofg-europe.net\",\n            \"fofg.org\",\n            \"fofldfradio.org\",\n            \"foolsmountain.com\",\n            \"fooooo.com\",\n            \"foreignaffairs.com\",\n            \"foreignpolicy.com\",\n            \"forum4hk.com\",\n            \"forums-free.com\",\n            \"fotile.me\",\n            \"fourthinternational.org\",\n            \"foxbusiness.com\",\n            \"foxdie.us\",\n            \"foxgay.com\",\n            \"foxsub.com\",\n            \"foxtang.com\",\n            \"fpmt-osel.org\",\n            \"fpmt.org\",\n            \"fpmt.tw\",\n            \"fpmtmexico.org\",\n            \"fqok.org\",\n            \"fqrouter.com\",\n            \"franklc.com\",\n            \"freakshare.com\",\n            \"free-gate.org\",\n            \"free-hada-now.org\",\n            \"free-proxy.cz\",\n            \"free-ss.site\",\n            \"free-ssh.com\",\n            \"free.fr\",\n            \"free4u.com.ar\",\n            \"freealim.com\",\n            \"freebeacon.com\",\n            \"freebearblog.org\",\n            \"freebrowser.org\",\n            \"freechal.com\",\n            \"freechina.net\",\n            \"freechina.news\",\n            \"freechinaforum.org\",\n            \"freechinaweibo.com\",\n            \"freeddns.com\",\n            \"freeddns.org\",\n            \"freedomchina.info\",\n            \"freedomcollection.org\",\n            \"freedomhouse.org\",\n            \"freedomsherald.org\",\n            \"freeforums.org\",\n            \"freefq.com\",\n            \"freefuckvids.com\",\n            \"freegao.com\",\n            \"freehongkong.org\",\n            \"freeilhamtohti.org\",\n            \"freekazakhs.org\",\n            \"freekwonpyong.org\",\n            \"freelotto.com\",\n            \"freeman2.com\",\n            \"freemoren.com\",\n            \"freemorenews.com\",\n            \"freemuse.org\",\n            \"freenet-china.org\",\n            \"freenetproject.org\",\n            \"freenewscn.com\",\n            \"freeones.com\",\n            \"freeopenvpn.com\",\n            \"freeoz.org\",\n            \"freerk.com\",\n            \"freessh.us\",\n            \"freetcp.com\",\n            \"freetibet.net\",\n            \"freetibet.org\",\n            \"freetibetanheroes.org\",\n            \"freetribe.me\",\n            \"freeviewmovies.com\",\n            \"freevpn.me\",\n            \"freevpn.nl\",\n            \"freewallpaper4.me\",\n            \"freewebs.com\",\n            \"freewechat.com\",\n            \"freeweibo.com\",\n            \"freewww.biz\",\n            \"freewww.info\",\n            \"freexinwen.com\",\n            \"freeyellow.com\",\n            \"freeyoutubeproxy.net\",\n            \"frienddy.com\",\n            \"friendfeed-media.com\",\n            \"friendfeed.com\",\n            \"friendfinder.com\",\n            \"friends-of-tibet.org\",\n            \"friendsoftibet.org\",\n            \"fring.com\",\n            \"fringenetwork.com\",\n            \"from-pr.com\",\n            \"from-sd.com\",\n            \"fromchinatousa.net\",\n            \"frommel.net\",\n            \"frontlinedefenders.org\",\n            \"frootvpn.com\",\n            \"fscked.org\",\n            \"fsurf.com\",\n            \"ftchinese.com\",\n            \"ftp1.biz\",\n            \"ftpserver.biz\",\n            \"ftv.com.tw\",\n            \"ftvnews.com.tw\",\n            \"ftx.com\",\n            \"fucd.com\",\n            \"fuckcnnic.net\",\n            \"fuckgfw.org\",\n            \"fuckgfw233.org\",\n            \"fulione.com\",\n            \"fullerconsideration.com\",\n            \"fulue.com\",\n            \"funf.tw\",\n            \"funkyimg.com\",\n            \"funp.com\",\n            \"fuq.com\",\n            \"furbo.org\",\n            \"furhhdl.org\",\n            \"furinkan.com\",\n            \"furl.net\",\n            \"futurechinaforum.org\",\n            \"futuremessage.org\",\n            \"fux.com\",\n            \"fuyin.net\",\n            \"fuyindiantai.org\",\n            \"fuyu.org.tw\",\n            \"fw.cm\",\n            \"fxcm-chinese.com\",\n            \"fxnetworks.com\",\n            \"fzh999.com\",\n            \"fzh999.net\",\n            \"fzlm.com\",\n            \"g-area.org\",\n            \"g-queen.com\",\n            \"g.co\",\n            \"g0v.social\",\n            \"g6hentai.com\",\n            \"gab.com\",\n            \"gabocorp.com\",\n            \"gaeproxy.com\",\n            \"gaforum.org\",\n            \"gagaoolala.com\",\n            \"galaxymacau.com\",\n            \"galenwu.com\",\n            \"galstars.net\",\n            \"game735.com\",\n            \"gamebase.com.tw\",\n            \"gamejolt.com\",\n            \"gamer.com.tw\",\n            \"gamerp.jp\",\n            \"gamez.com.tw\",\n            \"gamousa.com\",\n            \"ganges.com\",\n            \"ganjingworld.com\",\n            \"gaoming.net\",\n            \"gaopi.net\",\n            \"gaozhisheng.net\",\n            \"gaozhisheng.org\",\n            \"gardennetworks.com\",\n            \"gardennetworks.org\",\n            \"gartlive.com\",\n            \"gate-project.com\",\n            \"gate.io\",\n            \"gatecoin.com\",\n            \"gather.com\",\n            \"gatherproxy.com\",\n            \"gati.org.tw\",\n            \"gaybubble.com\",\n            \"gaycn.net\",\n            \"gayhub.com\",\n            \"gaymap.cc\",\n            \"gaymenring.com\",\n            \"gaytube.com\",\n            \"gaywatch.com\",\n            \"gazotube.com\",\n            \"gcc.org.hk\",\n            \"gclooney.com\",\n            \"gclubs.com\",\n            \"gcmasia.com\",\n            \"gcpnews.com\",\n            \"gcr.io\",\n            \"gdbt.net\",\n            \"gdzf.org\",\n            \"geek-art.net\",\n            \"geekerhome.com\",\n            \"geekheart.info\",\n            \"gekikame.com\",\n            \"gelbooru.com\",\n            \"genius.com\",\n            \"geocities.co.jp\",\n            \"geocities.com\",\n            \"geocities.jp\",\n            \"geph.io\",\n            \"gerefoundation.org\",\n            \"get.app\",\n            \"get.dev\",\n            \"get.how\",\n            \"get.page\",\n            \"getastrill.com\",\n            \"getchu.com\",\n            \"getcloak.com\",\n            \"getfoxyproxy.org\",\n            \"getfreedur.com\",\n            \"getgom.com\",\n            \"geti2p.net\",\n            \"getiton.com\",\n            \"getjetso.com\",\n            \"getlantern.org\",\n            \"getmalus.com\",\n            \"getmdl.io\",\n            \"getoutline.org\",\n            \"getsocialscope.com\",\n            \"getsync.com\",\n            \"gettr.com\",\n            \"gettrials.com\",\n            \"gettyimages.com\",\n            \"getuploader.com\",\n            \"gfbv.de\",\n            \"gfgold.com.hk\",\n            \"gfsale.com\",\n            \"gfw.org.ua\",\n            \"gfw.press\",\n            \"gfw.report\",\n            \"ggpht.com\",\n            \"ggssl.com\",\n            \"ghidra-sre.org\",\n            \"ghostpath.com\",\n            \"ghut.org\",\n            \"giantessnight.com\",\n            \"gifree.com\",\n            \"giga-web.jp\",\n            \"gigacircle.com\",\n            \"giganews.com\",\n            \"gigporno.ru\",\n            \"girlbanker.com\",\n            \"git.io\",\n            \"gitbooks.io\",\n            \"githack.com\",\n            \"github.blog\",\n            \"github.com\",\n            \"github.io\",\n            \"githubassets.com\",\n            \"githubusercontent.com\",\n            \"gizlen.net\",\n            \"gjczz.com\",\n            \"glass8.eu\",\n            \"globaljihad.net\",\n            \"globalmediaoutreach.com\",\n            \"globalmuseumoncommunism.org\",\n            \"globalrescue.net\",\n            \"globaltm.org\",\n            \"globalvoices.org\",\n            \"globalvoicesonline.org\",\n            \"globalvpn.net\",\n            \"glock.com\",\n            \"gloryhole.com\",\n            \"glorystar.me\",\n            \"gluckman.com\",\n            \"glype.com\",\n            \"gmail.com\",\n            \"gmgard.com\",\n            \"gmhz.org\",\n            \"gmiddle.com\",\n            \"gmiddle.net\",\n            \"gmll.org\",\n            \"gmodules.com\",\n            \"gmx.net\",\n            \"gnci.org.hk\",\n            \"gnews.org\",\n            \"go-pki.com\",\n            \"go141.com\",\n            \"goagent.biz\",\n            \"goagentplus.com\",\n            \"gobet.cc\",\n            \"godfootsteps.org\",\n            \"godns.work\",\n            \"godoc.org\",\n            \"godsdirectcontact.co.uk\",\n            \"godsdirectcontact.org\",\n            \"godsdirectcontact.org.tw\",\n            \"godsimmediatecontact.com\",\n            \"gofundme.com\",\n            \"gogotunnel.com\",\n            \"gohappy.com.tw\",\n            \"gokbayrak.com\",\n            \"golang.org\",\n            \"goldbet.com\",\n            \"goldbetsports.com\",\n            \"golden-ages.org\",\n            \"goldeneyevault.com\",\n            \"goldenfrog.com\",\n            \"goldjizz.com\",\n            \"goldstep.net\",\n            \"goldwave.com\",\n            \"gongm.in\",\n            \"gongmeng.info\",\n            \"gongminliliang.com\",\n            \"gongwt.com\",\n            \"goo.gl\",\n            \"goo.gle\",\n            \"goo.ne.jp\",\n            \"gooday.xyz\",\n            \"gooddns.info\",\n            \"goodhope.school\",\n            \"goodreaders.com\",\n            \"goodreads.com\",\n            \"goodtv.com.tw\",\n            \"goodtv.tv\",\n            \"goofind.com\",\n            \"google.ac\",\n            \"google.ad\",\n            \"google.ae\",\n            \"google.af\",\n            \"google.ai\",\n            \"google.al\",\n            \"google.am\",\n            \"google.as\",\n            \"google.at\",\n            \"google.az\",\n            \"google.ba\",\n            \"google.be\",\n            \"google.bf\",\n            \"google.bg\",\n            \"google.bi\",\n            \"google.bj\",\n            \"google.bs\",\n            \"google.bt\",\n            \"google.by\",\n            \"google.ca\",\n            \"google.cat\",\n            \"google.cd\",\n            \"google.cf\",\n            \"google.cg\",\n            \"google.ch\",\n            \"google.ci\",\n            \"google.cl\",\n            \"google.cm\",\n            \"google.cn\",\n            \"google.co.ao\",\n            \"google.co.bw\",\n            \"google.co.ck\",\n            \"google.co.cr\",\n            \"google.co.id\",\n            \"google.co.il\",\n            \"google.co.in\",\n            \"google.co.jp\",\n            \"google.co.ke\",\n            \"google.co.kr\",\n            \"google.co.ls\",\n            \"google.co.ma\",\n            \"google.co.mz\",\n            \"google.co.nz\",\n            \"google.co.th\",\n            \"google.co.tz\",\n            \"google.co.ug\",\n            \"google.co.uk\",\n            \"google.co.uz\",\n            \"google.co.ve\",\n            \"google.co.vi\",\n            \"google.co.za\",\n            \"google.co.zm\",\n            \"google.co.zw\",\n            \"google.com\",\n            \"google.com.af\",\n            \"google.com.ag\",\n            \"google.com.ai\",\n            \"google.com.ar\",\n            \"google.com.au\",\n            \"google.com.bd\",\n            \"google.com.bh\",\n            \"google.com.bn\",\n            \"google.com.bo\",\n            \"google.com.br\",\n            \"google.com.bz\",\n            \"google.com.co\",\n            \"google.com.cu\",\n            \"google.com.cy\",\n            \"google.com.do\",\n            \"google.com.ec\",\n            \"google.com.eg\",\n            \"google.com.et\",\n            \"google.com.fj\",\n            \"google.com.gh\",\n            \"google.com.gi\",\n            \"google.com.gt\",\n            \"google.com.hk\",\n            \"google.com.jm\",\n            \"google.com.kh\",\n            \"google.com.kw\",\n            \"google.com.lb\",\n            \"google.com.ly\",\n            \"google.com.mm\",\n            \"google.com.mt\",\n            \"google.com.mx\",\n            \"google.com.my\",\n            \"google.com.na\",\n            \"google.com.nf\",\n            \"google.com.ng\",\n            \"google.com.ni\",\n            \"google.com.np\",\n            \"google.com.om\",\n            \"google.com.pa\",\n            \"google.com.pe\",\n            \"google.com.pg\",\n            \"google.com.ph\",\n            \"google.com.pk\",\n            \"google.com.pr\",\n            \"google.com.py\",\n            \"google.com.qa\",\n            \"google.com.sa\",\n            \"google.com.sb\",\n            \"google.com.sg\",\n            \"google.com.sl\",\n            \"google.com.sv\",\n            \"google.com.tj\",\n            \"google.com.tr\",\n            \"google.com.tw\",\n            \"google.com.ua\",\n            \"google.com.uy\",\n            \"google.com.vc\",\n            \"google.com.vn\",\n            \"google.cv\",\n            \"google.cz\",\n            \"google.de\",\n            \"google.dev\",\n            \"google.dj\",\n            \"google.dk\",\n            \"google.dm\",\n            \"google.dz\",\n            \"google.ee\",\n            \"google.es\",\n            \"google.eu\",\n            \"google.fi\",\n            \"google.fm\",\n            \"google.fr\",\n            \"google.ga\",\n            \"google.ge\",\n            \"google.gg\",\n            \"google.gl\",\n            \"google.gm\",\n            \"google.gp\",\n            \"google.gr\",\n            \"google.gy\",\n            \"google.hk\",\n            \"google.hn\",\n            \"google.hr\",\n            \"google.ht\",\n            \"google.hu\",\n            \"google.ie\",\n            \"google.im\",\n            \"google.iq\",\n            \"google.is\",\n            \"google.it\",\n            \"google.it.ao\",\n            \"google.je\",\n            \"google.jo\",\n            \"google.kg\",\n            \"google.ki\",\n            \"google.kz\",\n            \"google.la\",\n            \"google.li\",\n            \"google.lk\",\n            \"google.lt\",\n            \"google.lu\",\n            \"google.lv\",\n            \"google.md\",\n            \"google.me\",\n            \"google.mg\",\n            \"google.mk\",\n            \"google.ml\",\n            \"google.mn\",\n            \"google.ms\",\n            \"google.mu\",\n            \"google.mv\",\n            \"google.mw\",\n            \"google.mx\",\n            \"google.ne\",\n            \"google.nl\",\n            \"google.no\",\n            \"google.nr\",\n            \"google.nu\",\n            \"google.org\",\n            \"google.pl\",\n            \"google.pn\",\n            \"google.ps\",\n            \"google.pt\",\n            \"google.ro\",\n            \"google.rs\",\n            \"google.ru\",\n            \"google.rw\",\n            \"google.sc\",\n            \"google.se\",\n            \"google.sh\",\n            \"google.si\",\n            \"google.sk\",\n            \"google.sm\",\n            \"google.sn\",\n            \"google.so\",\n            \"google.sr\",\n            \"google.st\",\n            \"google.td\",\n            \"google.tg\",\n            \"google.tk\",\n            \"google.tl\",\n            \"google.tm\",\n            \"google.tn\",\n            \"google.to\",\n            \"google.tt\",\n            \"google.us\",\n            \"google.vg\",\n            \"google.vn\",\n            \"google.vu\",\n            \"google.ws\",\n            \"googleapis.cn\",\n            \"googleapis.com\",\n            \"googleapps.com\",\n            \"googlearth.com\",\n            \"googleartproject.com\",\n            \"googleblog.com\",\n            \"googlebot.com\",\n            \"googlechinawebmaster.com\",\n            \"googlecode.com\",\n            \"googlecommerce.com\",\n            \"googledomains.com\",\n            \"googledrive.com\",\n            \"googleearth.com\",\n            \"googlefiber.net\",\n            \"googlegroups.com\",\n            \"googlehosted.com\",\n            \"googleideas.com\",\n            \"googleinsidesearch.com\",\n            \"googlelabs.com\",\n            \"googlemail.com\",\n            \"googlemashups.com\",\n            \"googlepagecreator.com\",\n            \"googleplay.com\",\n            \"googleplus.com\",\n            \"googlesile.com\",\n            \"googlesource.com\",\n            \"googleusercontent.com\",\n            \"googlevideo.com\",\n            \"googleweblight.com\",\n            \"googlezip.net\",\n            \"gopetition.com\",\n            \"goproxing.net\",\n            \"goreforum.com\",\n            \"goregrish.com\",\n            \"gospelherald.com\",\n            \"got-game.org\",\n            \"gotdns.ch\",\n            \"gotgeeks.com\",\n            \"gotrusted.com\",\n            \"gotw.ca\",\n            \"gov.taipei\",\n            \"gr8domain.biz\",\n            \"gr8name.biz\",\n            \"gradconnection.com\",\n            \"grammaly.com\",\n            \"grandtrial.org\",\n            \"grangorz.org\",\n            \"graphis.ne.jp\",\n            \"graphql.org\",\n            \"gravatar.com\",\n            \"greasespot.net\",\n            \"great-firewall.com\",\n            \"great-roc.org\",\n            \"greatfire.org\",\n            \"greatfirewall.biz\",\n            \"greatfirewallofchina.net\",\n            \"greatfirewallofchina.org\",\n            \"greatroc.org\",\n            \"greatroc.tw\",\n            \"greatzhonghua.org\",\n            \"greenfieldbookstore.com.hk\",\n            \"greenparty.org.tw\",\n            \"greenpeace.com.tw\",\n            \"greenpeace.org\",\n            \"greenreadings.com\",\n            \"greenvpn.net\",\n            \"greenvpn.org\",\n            \"grotty-monday.com\",\n            \"grow.google\",\n            \"gs-discuss.com\",\n            \"gsearch.media\",\n            \"gstatic.com\",\n            \"gtricks.com\",\n            \"gts-vpn.com\",\n            \"gtv.org\",\n            \"gtv1.org\",\n            \"gu-chu-sum.org\",\n            \"guaguass.com\",\n            \"guaguass.org\",\n            \"guancha.org\",\n            \"guaneryu.com\",\n            \"guangming.com.my\",\n            \"guangnianvpn.com\",\n            \"guardster.com\",\n            \"guishan.org\",\n            \"gumroad.com\",\n            \"gun-world.net\",\n            \"gunsamerica.com\",\n            \"gunsandammo.com\",\n            \"guo.media\",\n            \"guruonline.hk\",\n            \"gutteruncensored.com\",\n            \"gvlib.com\",\n            \"gvm.com.tw\",\n            \"gvt0.com\",\n            \"gvt1.com\",\n            \"gvt3.com\",\n            \"gwins.org\",\n            \"gwtproject.org\",\n            \"gyalwarinpoche.com\",\n            \"gyatsostudio.com\",\n            \"gzm.tv\",\n            \"gzone-anime.info\",\n            \"h-china.org\",\n            \"h-moe.com\",\n            \"h1n1china.org\",\n            \"h528.com\",\n            \"h5dm.com\",\n            \"h5galgame.me\",\n            \"hacg.club\",\n            \"hacg.in\",\n            \"hacg.li\",\n            \"hacg.me\",\n            \"hacg.red\",\n            \"hacken.cc\",\n            \"hacker.org\",\n            \"hackmd.io\",\n            \"hackthatphone.net\",\n            \"hahlo.com\",\n            \"hakkatv.org.tw\",\n            \"handcraftedsoftware.org\",\n            \"hanime.tv\",\n            \"hanminzu.org\",\n            \"hanunyi.com\",\n            \"hao.news\",\n            \"hao123.com\",\n            \"hao123img.com\",\n            \"happy-vpn.com\",\n            \"haproxy.org\",\n            \"hardsextube.com\",\n            \"harunyahya.com\",\n            \"hasi.wang\",\n            \"hautelook.com\",\n            \"hautelookcdn.com\",\n            \"have8.com\",\n            \"hbg.com\",\n            \"hbo.com\",\n            \"hclips.com\",\n            \"hdlt.me\",\n            \"hdtvb.net\",\n            \"hdzog.com\",\n            \"he.net\",\n            \"heartyit.com\",\n            \"heavy-r.com\",\n            \"hec.su\",\n            \"hecaitou.net\",\n            \"hechaji.com\",\n            \"heeact.edu.tw\",\n            \"hegre-art.com\",\n            \"helixstudios.net\",\n            \"helloandroid.com\",\n            \"helloqueer.com\",\n            \"helloss.pw\",\n            \"hellotxt.com\",\n            \"hellouk.org\",\n            \"helpeachpeople.com\",\n            \"helplinfen.com\",\n            \"helpster.de\",\n            \"helpuyghursnow.org\",\n            \"helpzhuling.org\",\n            \"hentai.to\",\n            \"hentaitube.tv\",\n            \"hentaivideoworld.com\",\n            \"heqinglian.net\",\n            \"here.com\",\n            \"heritage.org\",\n            \"heroku.com\",\n            \"heungkongdiscuss.com\",\n            \"hexieshe.com\",\n            \"hexieshe.xyz\",\n            \"hexxeh.net\",\n            \"heyuedi.com\",\n            \"heywire.com\",\n            \"heyzo.com\",\n            \"hgseav.com\",\n            \"hhdcb3office.org\",\n            \"hhthesakyatrizin.org\",\n            \"hi-on.org.tw\",\n            \"hidden-advent.org\",\n            \"hide.me\",\n            \"hidecloud.com\",\n            \"hidein.net\",\n            \"hideipvpn.com\",\n            \"hideman.net\",\n            \"hideme.nl\",\n            \"hidemy.name\",\n            \"hidemyass.com\",\n            \"hidemycomp.com\",\n            \"higfw.com\",\n            \"highpeakspureearth.com\",\n            \"highrockmedia.com\",\n            \"hightail.com\",\n            \"hihiforum.com\",\n            \"hihistory.net\",\n            \"hiitch.com\",\n            \"hikinggfw.org\",\n            \"hilive.tv\",\n            \"himalayan-foundation.org\",\n            \"himalayanglacier.com\",\n            \"himemix.com\",\n            \"himemix.net\",\n            \"hinet.net\",\n            \"hitbtc.com\",\n            \"hitomi.la\",\n            \"hiwifi.com\",\n            \"hizb-ut-tahrir.info\",\n            \"hizb-ut-tahrir.org\",\n            \"hizbuttahrir.org\",\n            \"hjclub.info\",\n            \"hk-pub.com\",\n            \"hk01.com\",\n            \"hk32168.com\",\n            \"hkacg.com\",\n            \"hkacg.net\",\n            \"hkatvnews.com\",\n            \"hkbc.net\",\n            \"hkbf.org\",\n            \"hkbookcity.com\",\n            \"hkchronicles.com\",\n            \"hkchurch.org\",\n            \"hkci.org.hk\",\n            \"hkcmi.edu\",\n            \"hkcnews.com\",\n            \"hkcoc.com\",\n            \"hkctu.org.hk\",\n            \"hkdailynews.com.hk\",\n            \"hkday.net\",\n            \"hkdc.us\",\n            \"hkdf.org\",\n            \"hkej.com\",\n            \"hkepc.com\",\n            \"hket.com\",\n            \"hkfaa.com\",\n            \"hkfreezone.com\",\n            \"hkfront.org\",\n            \"hkgalden.com\",\n            \"hkgolden.com\",\n            \"hkgpao.com\",\n            \"hkgreenradio.org\",\n            \"hkheadline.com\",\n            \"hkhkhk.com\",\n            \"hkhrc.org.hk\",\n            \"hkhrm.org.hk\",\n            \"hkip.org.uk\",\n            \"hkja.org.hk\",\n            \"hkjc.com\",\n            \"hkjp.org\",\n            \"hklft.com\",\n            \"hklts.org.hk\",\n            \"hkmap.live\",\n            \"hkopentv.com\",\n            \"hkpeanut.com\",\n            \"hkptu.org\",\n            \"hkreporter.com\",\n            \"hku.hk\",\n            \"hkusu.net\",\n            \"hkvwet.com\",\n            \"hkwcc.org.hk\",\n            \"hkzone.org\",\n            \"hmoegirl.com\",\n            \"hmonghot.com\",\n            \"hmv.co.jp\",\n            \"hmvdigital.ca\",\n            \"hmvdigital.com\",\n            \"hnjhj.com\",\n            \"hnntube.com\",\n            \"hola.com\",\n            \"hola.org\",\n            \"holymountaincn.com\",\n            \"holyspiritspeaks.org\",\n            \"homedepot.com\",\n            \"homeip.net\",\n            \"homeperversion.com\",\n            \"homeservershow.com\",\n            \"honeynet.org\",\n            \"hongkongfp.com\",\n            \"hongmeimei.com\",\n            \"hongzhi.li\",\n            \"honven.xyz\",\n            \"hootsuite.com\",\n            \"hoover.org\",\n            \"hoovers.com\",\n            \"hopedialogue.org\",\n            \"hopto.org\",\n            \"hornygamer.com\",\n            \"hornytrip.com\",\n            \"horrorporn.com\",\n            \"hotair.com\",\n            \"hotav.tv\",\n            \"hotels.cn\",\n            \"hotfrog.com.tw\",\n            \"hotgoo.com\",\n            \"hotpornshow.com\",\n            \"hotpot.hk\",\n            \"hotshame.com\",\n            \"hotspotshield.com\",\n            \"hottg.com\",\n            \"hotvpn.com\",\n            \"hougaige.com\",\n            \"howtoforge.com\",\n            \"hoxx.com\",\n            \"hpa.gov.tw\",\n            \"hqcdp.org\",\n            \"hqjapanesesex.com\",\n            \"hqmovies.com\",\n            \"hrcchina.org\",\n            \"hrcir.com\",\n            \"hrea.org\",\n            \"hrichina.org\",\n            \"hrtsea.com\",\n            \"hrw.org\",\n            \"hrweb.org\",\n            \"hsjp.net\",\n            \"hsselite.com\",\n            \"hst.net.tw\",\n            \"hstern.net\",\n            \"hstt.net\",\n            \"ht.ly\",\n            \"htkou.net\",\n            \"htl.li\",\n            \"html5rocks.com\",\n            \"https443.net\",\n            \"https443.org\",\n            \"hua-yue.net\",\n            \"huaglad.com\",\n            \"huanghuagang.org\",\n            \"huangyiyu.com\",\n            \"huaren.us\",\n            \"huaren4us.com\",\n            \"huashangnews.com\",\n            \"huasing.org\",\n            \"huaxia-news.com\",\n            \"huaxiabao.org\",\n            \"huaxin.ph\",\n            \"huayuworld.org\",\n            \"hudatoriq.web.id\",\n            \"hudson.org\",\n            \"huffingtonpost.com\",\n            \"hugoroy.eu\",\n            \"huhaitai.com\",\n            \"huhamhire.com\",\n            \"huhangfei.com\",\n            \"huiyi.in\",\n            \"hulkshare.com\",\n            \"hulu.com\",\n            \"huluim.com\",\n            \"hung-ya.com\",\n            \"hungerstrikeforaids.org\",\n            \"huobi.co\",\n            \"huobi.com\",\n            \"huobi.me\",\n            \"huobi.pro\",\n            \"huobi.sc\",\n            \"huobipro.com\",\n            \"huping.net\",\n            \"hurgokbayrak.com\",\n            \"hurriyet.com.tr\",\n            \"hustler.com\",\n            \"hustlercash.com\",\n            \"hut2.ru\",\n            \"hutianyi.net\",\n            \"hutong9.net\",\n            \"huyandex.com\",\n            \"hwadzan.tw\",\n            \"hwayue.org.tw\",\n            \"hwinfo.com\",\n            \"hxwk.org\",\n            \"hxwq.org\",\n            \"hybrid-analysis.com\",\n            \"hyperrate.com\",\n            \"hyread.com.tw\",\n            \"i-cable.com\",\n            \"i-part.com.tw\",\n            \"i-scmp.com\",\n            \"i1.hk\",\n            \"i2p2.de\",\n            \"i2runner.com\",\n            \"i818hk.com\",\n            \"iam.soy\",\n            \"iamtopone.com\",\n            \"iask.bz\",\n            \"iask.ca\",\n            \"iav19.com\",\n            \"ibiblio.org\",\n            \"ibit.am\",\n            \"iblist.com\",\n            \"iblogserv-f.net\",\n            \"ibros.org\",\n            \"ibtimes.com\",\n            \"ibvpn.com\",\n            \"icams.com\",\n            \"icerocket.com\",\n            \"icij.org\",\n            \"icl-fi.org\",\n            \"icoco.com\",\n            \"iconfactory.net\",\n            \"iconpaper.org\",\n            \"icu-project.org\",\n            \"idaiwan.com\",\n            \"idemocracy.asia\",\n            \"identi.ca\",\n            \"idiomconnection.com\",\n            \"idlcoyote.com\",\n            \"idouga.com\",\n            \"idreamx.com\",\n            \"idsam.com\",\n            \"ieasy5.com\",\n            \"ied2k.net\",\n            \"ienergy1.com\",\n            \"iepl.us\",\n            \"ifanqiang.com\",\n            \"ifcss.org\",\n            \"ifjc.org\",\n            \"ifreewares.com\",\n            \"ift.tt\",\n            \"igcd.net\",\n            \"igfw.net\",\n            \"igfw.tech\",\n            \"igmg.de\",\n            \"ignitedetroit.net\",\n            \"igoogle.com\",\n            \"igotmail.com.tw\",\n            \"igvita.com\",\n            \"ihakka.net\",\n            \"ihao.org\",\n            \"iicns.com\",\n            \"ikstar.com\",\n            \"ikwb.com\",\n            \"ilbe.com\",\n            \"ilhamtohtiinstitute.org\",\n            \"illusionfactory.com\",\n            \"ilove80.be\",\n            \"ilovelongtoes.com\",\n            \"im.tv\",\n            \"im88.tw\",\n            \"imageab.com\",\n            \"imagefap.com\",\n            \"imageflea.com\",\n            \"images-gaytube.com\",\n            \"imageshack.us\",\n            \"imagevenue.com\",\n            \"imagezilla.net\",\n            \"imb.org\",\n            \"imdb.com\",\n            \"img.ly\",\n            \"imgchili.net\",\n            \"imgmega.com\",\n            \"imgur.com\",\n            \"imkev.com\",\n            \"imlive.com\",\n            \"immigration.gov.tw\",\n            \"immoral.jp\",\n            \"impact.org.au\",\n            \"impp.mn\",\n            \"in-disguise.com\",\n            \"in.com\",\n            \"in99.org\",\n            \"incapdns.net\",\n            \"incloak.com\",\n            \"incredibox.fr\",\n            \"independent.co.uk\",\n            \"indiablooms.com\",\n            \"indianarrative.com\",\n            \"indiandefensenews.in\",\n            \"indiatimes.com\",\n            \"indiemerch.com\",\n            \"info-graf.fr\",\n            \"informer.com\",\n            \"initiativesforchina.org\",\n            \"inkui.com\",\n            \"inmediahk.net\",\n            \"innermongolia.org\",\n            \"inoreader.com\",\n            \"inote.tw\",\n            \"insecam.org\",\n            \"inside.com.tw\",\n            \"insidevoa.com\",\n            \"instagram.com\",\n            \"instanthq.com\",\n            \"institut-tibetain.org\",\n            \"internet.org\",\n            \"internetdefenseleague.org\",\n            \"internetfreedom.org\",\n            \"internetpopculture.com\",\n            \"inthenameofconfuciusmovie.com\",\n            \"inxian.com\",\n            \"iownyour.biz\",\n            \"iownyour.org\",\n            \"ipalter.com\",\n            \"ipfire.org\",\n            \"ipfs.io\",\n            \"iphone4hongkong.com\",\n            \"iphonehacks.com\",\n            \"iphonetaiwan.org\",\n            \"iphonix.fr\",\n            \"ipicture.ru\",\n            \"ipjetable.net\",\n            \"ipobar.com\",\n            \"ipoock.com\",\n            \"iportal.me\",\n            \"ippotv.com\",\n            \"ipredator.se\",\n            \"iptv.com.tw\",\n            \"iptvbin.com\",\n            \"ipvanish.com\",\n            \"iqiyi.com\",\n            \"iredmail.org\",\n            \"irib.ir\",\n            \"ironpython.net\",\n            \"ironsocket.com\",\n            \"is-a-hunter.com\",\n            \"is.gd\",\n            \"isaacmao.com\",\n            \"isasecret.com\",\n            \"isgreat.org\",\n            \"islahhaber.net\",\n            \"islam.org.hk\",\n            \"islamawareness.net\",\n            \"islamhouse.com\",\n            \"islamicity.com\",\n            \"islamicpluralism.org\",\n            \"islamtoday.net\",\n            \"ismaelan.com\",\n            \"ismalltits.com\",\n            \"ismprofessional.net\",\n            \"isohunt.com\",\n            \"israbox.com\",\n            \"issuu.com\",\n            \"istars.co.nz\",\n            \"istarshine.com\",\n            \"istef.info\",\n            \"istiqlalhewer.com\",\n            \"istockphoto.com\",\n            \"isunaffairs.com\",\n            \"isuntv.com\",\n            \"isupportuyghurs.org\",\n            \"itaboo.info\",\n            \"itaiwan.gov.tw\",\n            \"italiatibet.org\",\n            \"itasoftware.com\",\n            \"itemdb.com\",\n            \"ithome.com.tw\",\n            \"itsaol.com\",\n            \"itshidden.com\",\n            \"itsky.it\",\n            \"itweet.net\",\n            \"iu45.com\",\n            \"iuhrdf.org\",\n            \"iuksky.com\",\n            \"ivacy.com\",\n            \"iverycd.com\",\n            \"ivpn.net\",\n            \"ixquick.com\",\n            \"ixxx.com\",\n            \"iyouport.com\",\n            \"iyouport.org\",\n            \"izaobao.us\",\n            \"izihost.org\",\n            \"izles.net\",\n            \"izlesem.org\",\n            \"j.mp\",\n            \"jable.tv\",\n            \"jackjia.com\",\n            \"jamaat.org\",\n            \"jamestown.org\",\n            \"jamyangnorbu.com\",\n            \"jandyx.com\",\n            \"janwongphoto.com\",\n            \"japan-whores.com\",\n            \"japantimes.co.jp\",\n            \"jav.com\",\n            \"jav101.com\",\n            \"jav2be.com\",\n            \"jav68.tv\",\n            \"javakiba.org\",\n            \"javbus.com\",\n            \"javfor.me\",\n            \"javhd.com\",\n            \"javhip.com\",\n            \"javhub.net\",\n            \"javhuge.com\",\n            \"javlibrary.com\",\n            \"javmobile.net\",\n            \"javmoo.com\",\n            \"javmoo.xyz\",\n            \"javseen.com\",\n            \"javtag.com\",\n            \"javzoo.com\",\n            \"jbtalks.cc\",\n            \"jbtalks.com\",\n            \"jbtalks.my\",\n            \"jcpenney.com\",\n            \"jdwsy.com\",\n            \"jeanyim.com\",\n            \"jetos.com\",\n            \"jex.com\",\n            \"jfqu36.club\",\n            \"jfqu37.xyz\",\n            \"jgoodies.com\",\n            \"jiangweiping.com\",\n            \"jiaoyou8.com\",\n            \"jichangtj.com\",\n            \"jiehua.cz\",\n            \"jiepang.com\",\n            \"jieshibaobao.com\",\n            \"jigglegifs.com\",\n            \"jigong1024.com\",\n            \"jigsy.com\",\n            \"jihadology.net\",\n            \"jiji.com\",\n            \"jims.net\",\n            \"jinbushe.org\",\n            \"jingpin.org\",\n            \"jingsim.org\",\n            \"jinhai.de\",\n            \"jinpianwang.com\",\n            \"jinroukong.com\",\n            \"jintian.net\",\n            \"jinx.com\",\n            \"jiruan.net\",\n            \"jitouch.com\",\n            \"jizzthis.com\",\n            \"jjgirls.com\",\n            \"jkb.cc\",\n            \"jkforum.net\",\n            \"jkub.com\",\n            \"jma.go.jp\",\n            \"jmscult.com\",\n            \"joachims.org\",\n            \"jobso.tv\",\n            \"joinbbs.net\",\n            \"joinclubhouse.com\",\n            \"joinmastodon.org\",\n            \"joins.com\",\n            \"jornaldacidadeonline.com.br\",\n            \"journalchretien.net\",\n            \"journalofdemocracy.org\",\n            \"joymiihub.com\",\n            \"joyourself.com\",\n            \"jp.net\",\n            \"jpopforum.net\",\n            \"jqueryui.com\",\n            \"jsdelivr.net\",\n            \"jshell.net\",\n            \"jtvnw.net\",\n            \"jubushoushen.com\",\n            \"juhuaren.com\",\n            \"jukujo-club.com\",\n            \"juliepost.com\",\n            \"juliereyc.com\",\n            \"junauza.com\",\n            \"june4commemoration.org\",\n            \"junefourth-20.net\",\n            \"jungleheart.com\",\n            \"junglobal.net\",\n            \"juoaa.com\",\n            \"justdied.com\",\n            \"justfreevpn.com\",\n            \"justicefortenzin.org\",\n            \"justmysocks1.net\",\n            \"justpaste.it\",\n            \"justtristan.com\",\n            \"juyuange.org\",\n            \"juziyue.com\",\n            \"jwmusic.org\",\n            \"jyxf.net\",\n            \"k-doujin.net\",\n            \"ka-wai.com\",\n            \"kadokawa.co.jp\",\n            \"kagyu.org\",\n            \"kagyu.org.za\",\n            \"kagyumonlam.org\",\n            \"kagyunews.com.hk\",\n            \"kagyuoffice.org\",\n            \"kagyuoffice.org.tw\",\n            \"kaiyuan.de\",\n            \"kakao.com\",\n            \"kalachakralugano.org\",\n            \"kangye.org\",\n            \"kankan.today\",\n            \"kannewyork.com\",\n            \"kanshifang.com\",\n            \"kantie.org\",\n            \"kanzhongguo.com\",\n            \"kanzhongguo.eu\",\n            \"kaotic.com\",\n            \"karayou.com\",\n            \"karkhung.com\",\n            \"karmapa-teachings.org\",\n            \"karmapa.org\",\n            \"kawaiikawaii.jp\",\n            \"kawase.com\",\n            \"kba-tx.org\",\n            \"kcoolonline.com\",\n            \"kebrum.com\",\n            \"kechara.com\",\n            \"keepandshare.com\",\n            \"keezmovies.com\",\n            \"kendatire.com\",\n            \"kendincos.net\",\n            \"kenengba.com\",\n            \"keontech.net\",\n            \"kepard.com\",\n            \"keso.cn\",\n            \"kex.com\",\n            \"keycdn.com\",\n            \"khabdha.org\",\n            \"khatrimaza.org\",\n            \"khmusic.com.tw\",\n            \"kichiku-doujinko.com\",\n            \"kik.com\",\n            \"killwall.com\",\n            \"kimy.com.tw\",\n            \"kindleren.com\",\n            \"kingdomsalvation.org\",\n            \"kinghost.com\",\n            \"kingstone.com.tw\",\n            \"kink.com\",\n            \"kinmen.org.tw\",\n            \"kinmen.travel\",\n            \"kinokuniya.com\",\n            \"kir.jp\",\n            \"kissbbao.cn\",\n            \"kiwi.kz\",\n            \"kk-whys.co.jp\",\n            \"kkbox.com\",\n            \"kknews.cc\",\n            \"klip.me\",\n            \"kmuh.org.tw\",\n            \"knowledgerush.com\",\n            \"knowyourmeme.com\",\n            \"kobo.com\",\n            \"kobobooks.com\",\n            \"kodingen.com\",\n            \"kompozer.net\",\n            \"konachan.com\",\n            \"kone.com\",\n            \"koolsolutions.com\",\n            \"koornk.com\",\n            \"koranmandarin.com\",\n            \"korenan2.com\",\n            \"kqes.net\",\n            \"krtco.com.tw\",\n            \"ksdl.org\",\n            \"ksnews.com.tw\",\n            \"kspcoin.com\",\n            \"ktzhk.com\",\n            \"kucoin.com\",\n            \"kui.name\",\n            \"kukuku.uk\",\n            \"kun.im\",\n            \"kurashsultan.com\",\n            \"kurtmunger.com\",\n            \"kusocity.com\",\n            \"kwcg.ca\",\n            \"kwok7.com\",\n            \"kwongwah.com.my\",\n            \"kxsw.life\",\n            \"kyofun.com\",\n            \"kyohk.net\",\n            \"kyoyue.com\",\n            \"kyzyhello.com\",\n            \"kzeng.info\",\n            \"la-forum.org\",\n            \"labiennale.org\",\n            \"ladbrokes.com\",\n            \"lagranepoca.com\",\n            \"lala.im\",\n            \"lalulalu.com\",\n            \"lama.com.tw\",\n            \"lamayeshe.com\",\n            \"lamenhu.com\",\n            \"lamnia.co.uk\",\n            \"lamrim.com\",\n            \"landofhope.tv\",\n            \"lanterncn.cn\",\n            \"lantosfoundation.org\",\n            \"laod.cn\",\n            \"laogai.org\",\n            \"laogairesearch.org\",\n            \"laomiu.com\",\n            \"laoyang.info\",\n            \"laptoplockdown.com\",\n            \"laqingdan.net\",\n            \"larsgeorge.com\",\n            \"lastcombat.com\",\n            \"lastfm.es\",\n            \"latelinenews.com\",\n            \"lausan.hk\",\n            \"law.com\",\n            \"lbank.info\",\n            \"le-vpn.com\",\n            \"leafyvpn.net\",\n            \"lecloud.net\",\n            \"leeao.com.cn\",\n            \"lefora.com\",\n            \"left21.hk\",\n            \"legalporno.com\",\n            \"legsjapan.com\",\n            \"leirentv.ca\",\n            \"leisurecafe.ca\",\n            \"leisurepro.com\",\n            \"lematin.ch\",\n            \"lemonde.fr\",\n            \"lenwhite.com\",\n            \"leorockwell.com\",\n            \"lerosua.org\",\n            \"lers.google\",\n            \"lesoir.be\",\n            \"lester850.info\",\n            \"letou.com\",\n            \"letscorp.net\",\n            \"letsencrypt.org\",\n            \"levyhsu.com\",\n            \"lflink.com\",\n            \"lflinkup.com\",\n            \"lflinkup.net\",\n            \"lflinkup.org\",\n            \"lfpcontent.com\",\n            \"lhakar.org\",\n            \"lhasocialwork.org\",\n            \"liangyou.net\",\n            \"liangzhichuanmei.com\",\n            \"lianyue.net\",\n            \"liaowangxizang.net\",\n            \"liberal.org.hk\",\n            \"libertytimes.com.tw\",\n            \"libraryinformationtechnology.com\",\n            \"libredd.it\",\n            \"lifemiles.com\",\n            \"lighten.org.tw\",\n            \"lighti.me\",\n            \"lightnovel.cn\",\n            \"lightyearvpn.com\",\n            \"lihkg.com\",\n            \"like.com\",\n            \"limiao.net\",\n            \"line-apps.com\",\n            \"line-scdn.net\",\n            \"line.me\",\n            \"linglingfa.com\",\n            \"lingvodics.com\",\n            \"link-o-rama.com\",\n            \"linkedin.com\",\n            \"linkideo.com\",\n            \"linksalpha.com\",\n            \"linkuswell.com\",\n            \"linpie.com\",\n            \"linux.org.hk\",\n            \"linuxtoy.org\",\n            \"lionsroar.com\",\n            \"lipuman.com\",\n            \"liquiditytp.com\",\n            \"liquidvpn.com\",\n            \"list-manage.com\",\n            \"listennotes.com\",\n            \"listentoyoutube.com\",\n            \"listorious.com\",\n            \"lithium.com\",\n            \"liu-xiaobo.org\",\n            \"liudejun.com\",\n            \"liuhanyu.com\",\n            \"liujianshu.com\",\n            \"liuxiaobo.net\",\n            \"liuxiaotong.com\",\n            \"live.com\",\n            \"livecoin.net\",\n            \"livedoor.jp\",\n            \"liveleak.com\",\n            \"livemint.com\",\n            \"livestation.com\",\n            \"livestream.com\",\n            \"livevideo.com\",\n            \"livingonline.us\",\n            \"livingstream.com\",\n            \"liwangyang.com\",\n            \"lizhizhuangbi.com\",\n            \"lkcn.net\",\n            \"llss.me\",\n            \"lncn.org\",\n            \"load.to\",\n            \"lobsangwangyal.com\",\n            \"localbitcoins.com\",\n            \"localdomain.ws\",\n            \"localpresshk.com\",\n            \"lockestek.com\",\n            \"logbot.net\",\n            \"logiqx.com\",\n            \"logmein.com\",\n            \"logos.com.hk\",\n            \"londonchinese.ca\",\n            \"longhair.hk\",\n            \"longmusic.com\",\n            \"longtermly.net\",\n            \"longtoes.com\",\n            \"lookpic.com\",\n            \"looktoronto.com\",\n            \"lotsawahouse.org\",\n            \"lotuslight.org.hk\",\n            \"lotuslight.org.tw\",\n            \"loved.hk\",\n            \"lovetvshow.com\",\n            \"lpsg.com\",\n            \"lrfz.com\",\n            \"lrip.org\",\n            \"lsd.org.hk\",\n            \"lsforum.net\",\n            \"lsm.org\",\n            \"lsmchinese.org\",\n            \"lsmkorean.org\",\n            \"lsmradio.com\",\n            \"lsmwebcast.com\",\n            \"lsxszzg.com\",\n            \"ltn.com.tw\",\n            \"luckydesigner.space\",\n            \"luke54.com\",\n            \"luke54.org\",\n            \"lupm.org\",\n            \"lushstories.com\",\n            \"luxebc.com\",\n            \"lvhai.org\",\n            \"lvv2.com\",\n            \"lyfhk.net\",\n            \"lzjscript.com\",\n            \"lzmtnews.org\",\n            \"m-sport.co.uk\",\n            \"m-team.cc\",\n            \"m.me\",\n            \"macgamestore.com\",\n            \"macrovpn.com\",\n            \"macts.com.tw\",\n            \"mad-ar.ch\",\n            \"madewithcode.com\",\n            \"madonna-av.com\",\n            \"madrau.com\",\n            \"madthumbs.com\",\n            \"magic-net.info\",\n            \"mahabodhi.org\",\n            \"maiio.net\",\n            \"mail-archive.com\",\n            \"mail.ru\",\n            \"mailchimp.com\",\n            \"maildns.xyz\",\n            \"maiplus.com\",\n            \"maizhong.org\",\n            \"makemymood.com\",\n            \"makkahnewspaper.com\",\n            \"malaysiakini.com\",\n            \"mamingzhe.com\",\n            \"manchukuo.net\",\n            \"mandiant.com\",\n            \"mangafox.com\",\n            \"mangafox.me\",\n            \"maniash.com\",\n            \"manicur4ik.ru\",\n            \"mansion.com\",\n            \"mansionpoker.com\",\n            \"manta.com\",\n            \"manyvoices.news\",\n            \"maplew.com\",\n            \"marc.info\",\n            \"marguerite.su\",\n            \"martau.com\",\n            \"martincartoons.com\",\n            \"martinoei.com\",\n            \"martsangkagyuofficial.org\",\n            \"maruta.be\",\n            \"marxist.com\",\n            \"marxist.net\",\n            \"marxists.org\",\n            \"mash.to\",\n            \"maskedip.com\",\n            \"mastodon.cloud\",\n            \"mastodon.host\",\n            \"mastodon.social\",\n            \"mastodon.xyz\",\n            \"matainja.com\",\n            \"material.io\",\n            \"mathable.io\",\n            \"mathiew-badimon.com\",\n            \"matome-plus.com\",\n            \"matome-plus.net\",\n            \"matrix.org\",\n            \"matsushimakaede.com\",\n            \"matters.news\",\n            \"mattwilcox.net\",\n            \"maturejp.com\",\n            \"maxing.jp\",\n            \"mayimayi.com\",\n            \"mcadforums.com\",\n            \"mcaf.ee\",\n            \"mcfog.com\",\n            \"mcreasite.com\",\n            \"md-t.org\",\n            \"me.me\",\n            \"meansys.com\",\n            \"media.org.hk\",\n            \"mediachinese.com\",\n            \"mediafire.com\",\n            \"mediafreakcity.com\",\n            \"medium.com\",\n            \"meetav.com\",\n            \"meetup.com\",\n            \"mefeedia.com\",\n            \"meforum.org\",\n            \"mefound.com\",\n            \"mega.co.nz\",\n            \"mega.io\",\n            \"mega.nz\",\n            \"megaproxy.com\",\n            \"megarotic.com\",\n            \"megavideo.com\",\n            \"megurineluka.com\",\n            \"meizhong.blog\",\n            \"meizhong.report\",\n            \"meltoday.com\",\n            \"memehk.com\",\n            \"memorybbs.com\",\n            \"memri.org\",\n            \"memrijttm.org\",\n            \"mercatox.com\",\n            \"mercdn.net\",\n            \"mercyprophet.org\",\n            \"mergersandinquisitions.org\",\n            \"meridian-trust.org\",\n            \"meripet.biz\",\n            \"meripet.com\",\n            \"merit-times.com.tw\",\n            \"meshrep.com\",\n            \"mesotw.com\",\n            \"messenger.com\",\n            \"metacafe.com\",\n            \"metafilter.com\",\n            \"metart.com\",\n            \"metarthunter.com\",\n            \"meteorshowersonline.com\",\n            \"metro.taipei\",\n            \"metrohk.com.hk\",\n            \"metrolife.ca\",\n            \"metroradio.com.hk\",\n            \"mewe.com\",\n            \"meyou.jp\",\n            \"meyul.com\",\n            \"mfxmedia.com\",\n            \"mgoon.com\",\n            \"mgstage.com\",\n            \"mh4u.org\",\n            \"mhradio.org\",\n            \"michaelanti.com\",\n            \"michaelmarketl.com\",\n            \"microvpn.com\",\n            \"middle-way.net\",\n            \"mihk.hk\",\n            \"mihr.com\",\n            \"mihua.org\",\n            \"mikesoltys.com\",\n            \"mikocon.com\",\n            \"milph.net\",\n            \"milsurps.com\",\n            \"mimiai.net\",\n            \"mimivip.com\",\n            \"mimivv.com\",\n            \"mindrolling.org\",\n            \"mingdemedia.org\",\n            \"minghui-a.org\",\n            \"minghui-b.org\",\n            \"minghui-school.org\",\n            \"minghui.or.kr\",\n            \"minghui.org\",\n            \"mingjinglishi.com\",\n            \"mingjingnews.com\",\n            \"mingjingtimes.com\",\n            \"mingpao.com\",\n            \"mingpaocanada.com\",\n            \"mingpaomonthly.com\",\n            \"mingpaonews.com\",\n            \"mingpaony.com\",\n            \"mingpaosf.com\",\n            \"mingpaotor.com\",\n            \"mingpaovan.com\",\n            \"mingshengbao.com\",\n            \"minhhue.net\",\n            \"miniforum.org\",\n            \"ministrybooks.org\",\n            \"minzhuhua.net\",\n            \"minzhuzhanxian.com\",\n            \"minzhuzhongguo.org\",\n            \"miroguide.com\",\n            \"mirrorbooks.com\",\n            \"mirrormedia.mg\",\n            \"mist.vip\",\n            \"mit.edu\",\n            \"mitao.com.tw\",\n            \"mitbbs.com\",\n            \"mitbbsau.com\",\n            \"mixero.com\",\n            \"mixi.jp\",\n            \"mixpod.com\",\n            \"mixx.com\",\n            \"mizzmona.com\",\n            \"mjib.gov.tw\",\n            \"mk5000.com\",\n            \"mlcool.com\",\n            \"mlzs.work\",\n            \"mm-cg.com\",\n            \"mmaaxx.com\",\n            \"mmmca.com\",\n            \"mnewstv.com\",\n            \"mobatek.net\",\n            \"mobile01.com\",\n            \"mobileways.de\",\n            \"moby.to\",\n            \"mobypicture.com\",\n            \"mod.io\",\n            \"modernchinastudies.org\",\n            \"moeaic.gov.tw\",\n            \"moeerolibrary.com\",\n            \"moegirl.org\",\n            \"mofa.gov.tw\",\n            \"mofaxiehui.com\",\n            \"mofos.com\",\n            \"mog.com\",\n            \"mohu.club\",\n            \"mohu.ml\",\n            \"mohu.rocks\",\n            \"mojim.com\",\n            \"mol.gov.tw\",\n            \"molihua.org\",\n            \"monar.ch\",\n            \"mondex.org\",\n            \"money-link.com.tw\",\n            \"moneyhome.biz\",\n            \"monitorchina.org\",\n            \"monitorware.com\",\n            \"monlamit.org\",\n            \"monster.com\",\n            \"moodyz.com\",\n            \"moon.fm\",\n            \"moonbbs.com\",\n            \"moonbingo.com\",\n            \"moptt.tw\",\n            \"morbell.com\",\n            \"morningsun.org\",\n            \"moroneta.com\",\n            \"mos.ru\",\n            \"motherless.com\",\n            \"motiyun.com\",\n            \"motor4ik.ru\",\n            \"mousebreaker.com\",\n            \"movements.org\",\n            \"moviefap.com\",\n            \"moztw.org\",\n            \"mp3buscador.com\",\n            \"mpettis.com\",\n            \"mpfinance.com\",\n            \"mpinews.com\",\n            \"mponline.hk\",\n            \"mqxd.org\",\n            \"mrbasic.com\",\n            \"mrbonus.com\",\n            \"mrface.com\",\n            \"mrslove.com\",\n            \"mrtweet.com\",\n            \"msa-it.org\",\n            \"msguancha.com\",\n            \"msha.gov\",\n            \"msn.com\",\n            \"msn.com.tw\",\n            \"mswe1.org\",\n            \"mthruf.com\",\n            \"mtw.tl\",\n            \"mubi.com\",\n            \"muchosucko.com\",\n            \"mullvad.net\",\n            \"multiply.com\",\n            \"multiproxy.org\",\n            \"multiupload.com\",\n            \"mummysgold.com\",\n            \"murmur.tw\",\n            \"musicade.net\",\n            \"muslimvideo.com\",\n            \"muzi.com\",\n            \"muzi.net\",\n            \"muzu.tv\",\n            \"mvdis.gov.tw\",\n            \"mvg.jp\",\n            \"mx981.com\",\n            \"my-formosa.com\",\n            \"my-private-network.co.uk\",\n            \"my-proxy.com\",\n            \"my03.com\",\n            \"my903.com\",\n            \"myactimes.com\",\n            \"myanniu.com\",\n            \"myaudiocast.com\",\n            \"myav.com.tw\",\n            \"mybbs.us\",\n            \"mybet.com\",\n            \"myca168.com\",\n            \"mycanadanow.com\",\n            \"mychat.to\",\n            \"mychinamyhome.com\",\n            \"mychinanet.com\",\n            \"mychinanews.com\",\n            \"mychinese.news\",\n            \"mycnnews.com\",\n            \"mycould.com\",\n            \"mydad.info\",\n            \"myddns.com\",\n            \"myeasytv.com\",\n            \"myeclipseide.com\",\n            \"myforum.com.hk\",\n            \"myfreecams.com\",\n            \"myfreepaysite.com\",\n            \"myfreshnet.com\",\n            \"myftp.info\",\n            \"myftp.name\",\n            \"myiphide.com\",\n            \"mykomica.org\",\n            \"mylftv.com\",\n            \"mymaji.com\",\n            \"mymediarom.com\",\n            \"mymoe.moe\",\n            \"mymom.info\",\n            \"mymusic.net.tw\",\n            \"mynetav.net\",\n            \"mynetav.org\",\n            \"mynumber.org\",\n            \"myparagliding.com\",\n            \"mypicture.info\",\n            \"mypikpak.com\",\n            \"mypop3.net\",\n            \"mypop3.org\",\n            \"mypopescu.com\",\n            \"myradio.hk\",\n            \"myreadingmanga.info\",\n            \"mysecondarydns.com\",\n            \"mysinablog.com\",\n            \"myspace.com\",\n            \"myspacecdn.com\",\n            \"mytalkbox.com\",\n            \"mytizi.com\",\n            \"mywww.biz\",\n            \"myz.info\",\n            \"naacoalition.org\",\n            \"nabble.com\",\n            \"naitik.net\",\n            \"nakido.com\",\n            \"nakuz.com\",\n            \"nalandabodhi.org\",\n            \"nalandawest.org\",\n            \"namgyal.org\",\n            \"namgyalmonastery.org\",\n            \"namsisi.com\",\n            \"nanyang.com\",\n            \"nanyangpost.com\",\n            \"nanzao.com\",\n            \"naol.ca\",\n            \"naol.cc\",\n            \"narod.ru\",\n            \"nasa.gov\",\n            \"nat.gov.tw\",\n            \"nat.moe\",\n            \"natado.com\",\n            \"national-lottery.co.uk\",\n            \"nationalawakening.org\",\n            \"nationalgeographic.com\",\n            \"nationalinterest.org\",\n            \"nationalreview.com\",\n            \"nationsonline.org\",\n            \"nationwide.com\",\n            \"naughtyamerica.com\",\n            \"naver.jp\",\n            \"navy.mil\",\n            \"naweeklytimes.com\",\n            \"nbc.com\",\n            \"nbcnews.com\",\n            \"nbtvpn.com\",\n            \"nccwatch.org.tw\",\n            \"nch.com.tw\",\n            \"nchrd.org\",\n            \"ncn.org\",\n            \"ncol.com\",\n            \"nde.de\",\n            \"ndi.org\",\n            \"ndr.de\",\n            \"ned.org\",\n            \"nekoslovakia.net\",\n            \"neo-miracle.com\",\n            \"neowin.net\",\n            \"nepusoku.com\",\n            \"nesnode.com\",\n            \"net-fits.pro\",\n            \"netalert.me\",\n            \"netbig.com\",\n            \"netbirds.com\",\n            \"netcolony.com\",\n            \"netfirms.com\",\n            \"netflav.com\",\n            \"netflix.com\",\n            \"netflix.net\",\n            \"netme.cc\",\n            \"netsarang.com\",\n            \"netsneak.com\",\n            \"network54.com\",\n            \"networkedblogs.com\",\n            \"networktunnel.net\",\n            \"neverforget8964.org\",\n            \"new-3lunch.net\",\n            \"new-akiba.com\",\n            \"new96.ca\",\n            \"newcenturymc.com\",\n            \"newcenturynews.com\",\n            \"newchen.com\",\n            \"newgrounds.com\",\n            \"newhighlandvision.com\",\n            \"newipnow.com\",\n            \"newlandmagazine.com.au\",\n            \"newnews.ca\",\n            \"news100.com.tw\",\n            \"newsancai.com\",\n            \"newschinacomment.org\",\n            \"newscn.org\",\n            \"newsdetox.ca\",\n            \"newsdh.com\",\n            \"newsmagazine.asia\",\n            \"newsmax.com\",\n            \"newspeak.cc\",\n            \"newstamago.com\",\n            \"newstapa.org\",\n            \"newstarnet.com\",\n            \"newstatesman.com\",\n            \"newsweek.com\",\n            \"newtaiwan.com.tw\",\n            \"newtalk.tw\",\n            \"newyorker.com\",\n            \"newyorktimes.com\",\n            \"nexon.com\",\n            \"next11.co.jp\",\n            \"nextdigital.com.hk\",\n            \"nextmag.com.tw\",\n            \"nextmedia.com\",\n            \"nexton-net.jp\",\n            \"nexttv.com.tw\",\n            \"nf.id.au\",\n            \"nfjtyd.com\",\n            \"nflxext.com\",\n            \"nflximg.com\",\n            \"nflximg.net\",\n            \"nflxso.net\",\n            \"nflxvideo.net\",\n            \"ng.mil\",\n            \"nga.mil\",\n            \"ngensis.com\",\n            \"ngodupdongchung.com\",\n            \"nhentai.net\",\n            \"nhi.gov.tw\",\n            \"nhk-ondemand.jp\",\n            \"nic.google\",\n            \"nic.gov\",\n            \"nicovideo.jp\",\n            \"nighost.org\",\n            \"nightlife141.com\",\n            \"nike.com\",\n            \"nikkei.com\",\n            \"ninecommentaries.com\",\n            \"ning.com\",\n            \"ninjacloak.com\",\n            \"ninjaproxy.ninja\",\n            \"nintendium.com\",\n            \"ninth.biz\",\n            \"nitter.cc\",\n            \"nitter.net\",\n            \"niu.moe\",\n            \"niusnews.com\",\n            \"njactb.org\",\n            \"njuice.com\",\n            \"nlfreevpn.com\",\n            \"nmsl.website\",\n            \"nnews.eu\",\n            \"no-ip.com\",\n            \"no-ip.org\",\n            \"nobel.se\",\n            \"nobelprize.org\",\n            \"nobodycanstop.us\",\n            \"nodesnoop.com\",\n            \"nofile.io\",\n            \"nokogiri.org\",\n            \"nokola.com\",\n            \"noodlevpn.com\",\n            \"norbulingka.org\",\n            \"nordstrom.com\",\n            \"nordstromimage.com\",\n            \"nordstromrack.com\",\n            \"nordvpn.com\",\n            \"notepad-plus-plus.org\",\n            \"nottinghampost.com\",\n            \"novelasia.com\",\n            \"now.com\",\n            \"now.im\",\n            \"nownews.com\",\n            \"nowtorrents.com\",\n            \"noxinfluencer.com\",\n            \"noypf.com\",\n            \"npa.go.jp\",\n            \"npa.gov.tw\",\n            \"npnt.me\",\n            \"nps.gov\",\n            \"npsboost.com\",\n            \"nradio.me\",\n            \"nrk.no\",\n            \"ns01.biz\",\n            \"ns01.info\",\n            \"ns01.us\",\n            \"ns02.biz\",\n            \"ns02.info\",\n            \"ns02.us\",\n            \"ns1.name\",\n            \"ns2.name\",\n            \"ns3.name\",\n            \"nsc.gov.tw\",\n            \"ntbk.gov.tw\",\n            \"ntbna.gov.tw\",\n            \"ntbt.gov.tw\",\n            \"ntd.tv\",\n            \"ntdtv.ca\",\n            \"ntdtv.co.kr\",\n            \"ntdtv.com\",\n            \"ntdtv.com.tw\",\n            \"ntdtv.cz\",\n            \"ntdtv.org\",\n            \"ntdtv.ru\",\n            \"ntdtvla.com\",\n            \"ntrfun.com\",\n            \"ntsna.gov.tw\",\n            \"ntu.edu.tw\",\n            \"nu.nl\",\n            \"nubiles.net\",\n            \"nudezz.com\",\n            \"nuexpo.com\",\n            \"nukistream.com\",\n            \"nurgo-software.com\",\n            \"nusatrip.com\",\n            \"nutaku.net\",\n            \"nutsvpn.work\",\n            \"nuuvem.com\",\n            \"nuvid.com\",\n            \"nuzcom.com\",\n            \"nvdst.com\",\n            \"nvquan.org\",\n            \"nvtongzhisheng.org\",\n            \"nwtca.org\",\n            \"nyaa.eu\",\n            \"nyaa.si\",\n            \"nybooks.com\",\n            \"nydus.ca\",\n            \"nylon-angel.com\",\n            \"nylonstockingsonline.com\",\n            \"nypost.com\",\n            \"nyt.com\",\n            \"nytchina.com\",\n            \"nytcn.me\",\n            \"nytco.com\",\n            \"nyti.ms\",\n            \"nytimes.com\",\n            \"nytimg.com\",\n            \"nytlog.com\",\n            \"nytstyle.com\",\n            \"nzchinese.com\",\n            \"nzchinese.net.nz\",\n            \"oanda.com\",\n            \"oann.com\",\n            \"oauth.net\",\n            \"observechina.net\",\n            \"obutu.com\",\n            \"ocaspro.com\",\n            \"occupytiananmen.com\",\n            \"oclp.hk\",\n            \"ocreampies.com\",\n            \"ocry.com\",\n            \"october-review.org\",\n            \"oculus.com\",\n            \"oculuscdn.com\",\n            \"odysee.com\",\n            \"oex.com\",\n            \"offbeatchina.com\",\n            \"officeoftibet.com\",\n            \"ofile.org\",\n            \"ogaoga.org\",\n            \"ogate.org\",\n            \"ohchr.org\",\n            \"ohmyrss.com\",\n            \"oikos.com.tw\",\n            \"oiktv.com\",\n            \"oizoblog.com\",\n            \"ok.ru\",\n            \"okayfreedom.com\",\n            \"okex.com\",\n            \"okk.tw\",\n            \"okx.com\",\n            \"olabloga.pl\",\n            \"old-cat.net\",\n            \"olevod.com\",\n            \"olumpo.com\",\n            \"olympicwatch.org\",\n            \"omct.org\",\n            \"omgili.com\",\n            \"omni7.jp\",\n            \"omnitalk.com\",\n            \"omnitalk.org\",\n            \"omny.fm\",\n            \"omy.sg\",\n            \"on.cc\",\n            \"on2.com\",\n            \"onapp.com\",\n            \"onedumb.com\",\n            \"onejav.com\",\n            \"onion.city\",\n            \"onion.ly\",\n            \"onlinecha.com\",\n            \"onlineyoutube.com\",\n            \"onlygayvideo.com\",\n            \"onlytweets.com\",\n            \"onmoon.com\",\n            \"onmoon.net\",\n            \"onmypc.biz\",\n            \"onmypc.info\",\n            \"onmypc.net\",\n            \"onmypc.org\",\n            \"onmypc.us\",\n            \"onthehunt.com\",\n            \"ontrac.com\",\n            \"oopsforum.com\",\n            \"open.com.hk\",\n            \"openallweb.com\",\n            \"opendemocracy.net\",\n            \"opendn.xyz\",\n            \"openervpn.in\",\n            \"openid.net\",\n            \"openleaks.org\",\n            \"opensea.io\",\n            \"opensource.google\",\n            \"opentech.fund\",\n            \"openvpn.net\",\n            \"openvpn.org\",\n            \"openwebster.com\",\n            \"openwrt.org.cn\",\n            \"opera-mini.net\",\n            \"opera.com\",\n            \"opus-gaming.com\",\n            \"orchidbbs.com\",\n            \"organcare.org.tw\",\n            \"organharvestinvestigation.net\",\n            \"organiccrap.com\",\n            \"orgasm.com\",\n            \"orgfree.com\",\n            \"oricon.co.jp\",\n            \"orient-doll.com\",\n            \"orientaldaily.com.my\",\n            \"orn.jp\",\n            \"orzdream.com\",\n            \"orzistic.org\",\n            \"osfoora.com\",\n            \"otcbtc.com\",\n            \"otnd.org\",\n            \"otto.de\",\n            \"otzo.com\",\n            \"ourdearamy.com\",\n            \"ourhobby.com\",\n            \"oursogo.com\",\n            \"oursteps.com.au\",\n            \"oursweb.net\",\n            \"ourtv.hk\",\n            \"over-blog.com\",\n            \"overcast.fm\",\n            \"overdaily.org\",\n            \"overplay.net\",\n            \"ovi.com\",\n            \"ovpn.com\",\n            \"ow.ly\",\n            \"owind.com\",\n            \"owl.li\",\n            \"owltail.com\",\n            \"oxfordscholarship.com\",\n            \"oxid.it\",\n            \"oyax.com\",\n            \"oyghan.com\",\n            \"ozchinese.com\",\n            \"ozvoice.org\",\n            \"ozxw.com\",\n            \"ozyoyo.com\",\n            \"pachosting.com\",\n            \"pacificpoker.com\",\n            \"packetix.net\",\n            \"pacopacomama.com\",\n            \"padmanet.com\",\n            \"page.tl\",\n            \"page2rss.com\",\n            \"pages.dev\",\n            \"pagodabox.com\",\n            \"palacemoon.com\",\n            \"paldengyal.com\",\n            \"paljorpublications.com\",\n            \"palmislife.com\",\n            \"paltalk.com\",\n            \"pandapow.co\",\n            \"pandapow.net\",\n            \"pandavpn-jp.com\",\n            \"pandavpnpro.com\",\n            \"pandora.com\",\n            \"pandora.tv\",\n            \"panluan.net\",\n            \"panoramio.com\",\n            \"pao-pao.net\",\n            \"paper.li\",\n            \"paperb.us\",\n            \"paradisehill.cc\",\n            \"paradisepoker.com\",\n            \"parkansky.com\",\n            \"parler.com\",\n            \"parse.com\",\n            \"parsevideo.com\",\n            \"partycasino.com\",\n            \"partypoker.com\",\n            \"passion.com\",\n            \"passiontimes.hk\",\n            \"paste.ee\",\n            \"pastebin.com\",\n            \"pastie.org\",\n            \"pathtosharepoint.com\",\n            \"patreon.com\",\n            \"paxful.com\",\n            \"pbs.org\",\n            \"pbwiki.com\",\n            \"pbworks.com\",\n            \"pbxes.com\",\n            \"pbxes.org\",\n            \"pcanywhere.net\",\n            \"pcc.gov.tw\",\n            \"pcdvd.com.tw\",\n            \"pchome.com.tw\",\n            \"pcij.org\",\n            \"pcloud.com\",\n            \"pcstore.com.tw\",\n            \"pct.org.tw\",\n            \"pdetails.com\",\n            \"pdproxy.com\",\n            \"peace.ca\",\n            \"peacefire.org\",\n            \"peacehall.com\",\n            \"pearlher.org\",\n            \"peeasian.com\",\n            \"peing.net\",\n            \"pekingduck.org\",\n            \"pemulihan.or.id\",\n            \"pen.io\",\n            \"penchinese.com\",\n            \"penchinese.net\",\n            \"pengyulong.com\",\n            \"penisbot.com\",\n            \"pentalogic.net\",\n            \"penthouse.com\",\n            \"pentoy.hk\",\n            \"peoplebookcafe.com\",\n            \"peoplenews.tw\",\n            \"peopo.org\",\n            \"percy.in\",\n            \"perfect-privacy.com\",\n            \"perfectgirls.net\",\n            \"periscope.tv\",\n            \"persecutionblog.com\",\n            \"persiankitty.com\",\n            \"phapluan.org\",\n            \"phayul.com\",\n            \"philborges.com\",\n            \"philly.com\",\n            \"phmsociety.org\",\n            \"phncdn.com\",\n            \"phonegap.com\",\n            \"photodharma.net\",\n            \"photofocus.com\",\n            \"phuquocservices.com\",\n            \"picacomic.com\",\n            \"picacomiccn.com\",\n            \"picasaweb.com\",\n            \"picidae.net\",\n            \"picturedip.com\",\n            \"picturesocial.com\",\n            \"pimg.tw\",\n            \"pin-cong.com\",\n            \"pin6.com\",\n            \"pincong.rocks\",\n            \"ping.fm\",\n            \"pinimg.com\",\n            \"pinkrod.com\",\n            \"pinoy-n.com\",\n            \"pinterest.at\",\n            \"pinterest.ca\",\n            \"pinterest.co.kr\",\n            \"pinterest.co.uk\",\n            \"pinterest.com\",\n            \"pinterest.com.mx\",\n            \"pinterest.de\",\n            \"pinterest.dk\",\n            \"pinterest.fr\",\n            \"pinterest.jp\",\n            \"pinterest.nl\",\n            \"pinterest.se\",\n            \"pipii.tv\",\n            \"piposay.com\",\n            \"piraattilahti.org\",\n            \"piring.com\",\n            \"pixelqi.com\",\n            \"pixiv.net\",\n            \"pixnet.in\",\n            \"pixnet.net\",\n            \"pk.com\",\n            \"pki.goog\",\n            \"placemix.com\",\n            \"playboy.com\",\n            \"playboyplus.com\",\n            \"player.fm\",\n            \"playno1.com\",\n            \"playpcesor.com\",\n            \"plays.com.tw\",\n            \"plexvpn.pro\",\n            \"plixi.com\",\n            \"plm.org.hk\",\n            \"plunder.com\",\n            \"plurk.com\",\n            \"plus.codes\",\n            \"plus28.com\",\n            \"plusbb.com\",\n            \"pmatehunter.com\",\n            \"pmates.com\",\n            \"po2b.com\",\n            \"pobieramy.top\",\n            \"podbean.com\",\n            \"podcast.co\",\n            \"podictionary.com\",\n            \"pokerstars.com\",\n            \"pokerstars.net\",\n            \"pokerstrategy.com\",\n            \"politicalchina.org\",\n            \"politicalconsultation.org\",\n            \"politiscales.net\",\n            \"poloniex.com\",\n            \"polymer-project.org\",\n            \"polymerhk.com\",\n            \"poolin.com\",\n            \"popo.tw\",\n            \"popvote.hk\",\n            \"popxi.click\",\n            \"popyard.com\",\n            \"popyard.org\",\n            \"porn.com\",\n            \"porn2.com\",\n            \"porn5.com\",\n            \"pornbase.org\",\n            \"pornerbros.com\",\n            \"pornhd.com\",\n            \"pornhost.com\",\n            \"pornhub.com\",\n            \"pornhubdeutsch.net\",\n            \"pornmm.net\",\n            \"pornoxo.com\",\n            \"pornrapidshare.com\",\n            \"pornsharing.com\",\n            \"pornsocket.com\",\n            \"pornstarclub.com\",\n            \"porntube.com\",\n            \"porntubenews.com\",\n            \"porntvblog.com\",\n            \"pornvisit.com\",\n            \"port25.biz\",\n            \"portablevpn.nl\",\n            \"poskotanews.com\",\n            \"post01.com\",\n            \"post76.com\",\n            \"post852.com\",\n            \"postadult.com\",\n            \"postimg.org\",\n            \"potato.im\",\n            \"potvpn.com\",\n            \"power.com\",\n            \"powerapple.com\",\n            \"powercx.com\",\n            \"powerphoto.org\",\n            \"powerpointninja.com\",\n            \"pp.ru\",\n            \"prayforchina.net\",\n            \"premeforwindows7.com\",\n            \"premproxy.com\",\n            \"presentationzen.com\",\n            \"presidentlee.tw\",\n            \"prestige-av.com\",\n            \"pride.google\",\n            \"printfriendly.com\",\n            \"prism-break.org\",\n            \"prisoneralert.com\",\n            \"pritunl.com\",\n            \"privacybox.de\",\n            \"private.com\",\n            \"privateinternetaccess.com\",\n            \"privatepaste.com\",\n            \"privatetunnel.com\",\n            \"privatevpn.com\",\n            \"privoxy.org\",\n            \"procopytips.com\",\n            \"project-syndicate.org\",\n            \"prosiben.de\",\n            \"proton.me\",\n            \"protonvpn.com\",\n            \"provideocoalition.com\",\n            \"provpnaccounts.com\",\n            \"proxfree.com\",\n            \"proxifier.com\",\n            \"proxlet.com\",\n            \"proxomitron.info\",\n            \"proxpn.com\",\n            \"proxyanonimo.es\",\n            \"proxydns.com\",\n            \"proxylist.org.uk\",\n            \"proxynetwork.org.uk\",\n            \"proxypy.net\",\n            \"proxyroad.com\",\n            \"proxytunnel.net\",\n            \"proyectoclubes.com\",\n            \"prozz.net\",\n            \"psblog.name\",\n            \"pscp.tv\",\n            \"pshvpn.com\",\n            \"psiphon.ca\",\n            \"psiphon3.com\",\n            \"psiphontoday.com\",\n            \"pt.im\",\n            \"pts.org.tw\",\n            \"ptt.cc\",\n            \"pttgame.com\",\n            \"pttvan.org\",\n            \"pubu.com.tw\",\n            \"puffinbrowser.com\",\n            \"puffstore.com\",\n            \"pullfolio.com\",\n            \"punyu.com\",\n            \"pure18.com\",\n            \"pureapk.com\",\n            \"pureconcepts.net\",\n            \"pureinsight.org\",\n            \"purepdf.com\",\n            \"purevpn.com\",\n            \"purplelotus.org\",\n            \"pursuestar.com\",\n            \"pushchinawall.com\",\n            \"pussthecat.org\",\n            \"pussyspace.com\",\n            \"putihome.org\",\n            \"putlocker.com\",\n            \"putty.org\",\n            \"puuko.com\",\n            \"pwned.com\",\n            \"pximg.net\",\n            \"python.com\",\n            \"python.com.tw\",\n            \"pythonhackers.com\",\n            \"pythonic.life\",\n            \"pytorch.org\",\n            \"qanote.com\",\n            \"qgirl.com.tw\",\n            \"qhigh.com\",\n            \"qi-gong.me\",\n            \"qianbai.tw\",\n            \"qiandao.today\",\n            \"qiangwaikan.com\",\n            \"qiangyou.org\",\n            \"qidian.ca\",\n            \"qienkuen.org\",\n            \"qiwen.lu\",\n            \"qixianglu.cn\",\n            \"qkshare.com\",\n            \"qmzdd.com\",\n            \"qoos.com\",\n            \"qooza.hk\",\n            \"qpoe.com\",\n            \"qq.co.za\",\n            \"qstatus.com\",\n            \"qtrac.eu\",\n            \"qtweeter.com\",\n            \"quannengshen.org\",\n            \"quantumbooter.net\",\n            \"questvisual.com\",\n            \"quitccp.net\",\n            \"quitccp.org\",\n            \"quora.com\",\n            \"quoracdn.net\",\n            \"quran.com\",\n            \"quranexplorer.com\",\n            \"qusi8.net\",\n            \"qvodzy.org\",\n            \"qx.net\",\n            \"qxbbs.org\",\n            \"qz.com\",\n            \"r0.ru\",\n            \"r18.com\",\n            \"ra.gg\",\n            \"radicalparty.org\",\n            \"radiko.jp\",\n            \"radio.garden\",\n            \"radioaustralia.net.au\",\n            \"radiohilight.net\",\n            \"radioline.co\",\n            \"radiotime.com\",\n            \"radiovaticana.org\",\n            \"radiovncr.com\",\n            \"rael.org\",\n            \"raggedbanner.com\",\n            \"raidcall.com.tw\",\n            \"raidtalk.com.tw\",\n            \"rainbowplan.org\",\n            \"raindrop.io\",\n            \"raizoji.or.jp\",\n            \"ramcity.com.au\",\n            \"rangwang.biz\",\n            \"rangzen.com\",\n            \"rangzen.net\",\n            \"rangzen.org\",\n            \"ranxiang.com\",\n            \"ranyunfei.com\",\n            \"rapbull.net\",\n            \"rapidgator.net\",\n            \"rapidmoviez.com\",\n            \"rapidvpn.com\",\n            \"rarbgprx.org\",\n            \"raremovie.cc\",\n            \"raremovie.net\",\n            \"rateyourmusic.com\",\n            \"rationalwiki.org\",\n            \"rawgit.com\",\n            \"rawgithub.com\",\n            \"raxcdn.com\",\n            \"razyboard.com\",\n            \"rcinet.ca\",\n            \"rd.com\",\n            \"rdio.com\",\n            \"read01.com\",\n            \"read100.com\",\n            \"readingtimes.com.tw\",\n            \"readmoo.com\",\n            \"readydown.com\",\n            \"realcourage.org\",\n            \"realitykings.com\",\n            \"realraptalk.com\",\n            \"realsexpass.com\",\n            \"reason.com\",\n            \"rebatesrule.net\",\n            \"recaptcha.net\",\n            \"recordhistory.org\",\n            \"recovery.org.tw\",\n            \"recoveryversion.com.tw\",\n            \"recoveryversion.org\",\n            \"red-lang.org\",\n            \"redballoonsolidarity.org\",\n            \"redbubble.com\",\n            \"redchinacn.net\",\n            \"redchinacn.org\",\n            \"redd.it\",\n            \"reddit.com\",\n            \"redditlist.com\",\n            \"redditmedia.com\",\n            \"redditstatic.com\",\n            \"redhotlabs.com\",\n            \"redtube.com\",\n            \"referer.us\",\n            \"reflectivecode.com\",\n            \"registry.google\",\n            \"relaxbbs.com\",\n            \"relay.com.tw\",\n            \"releaseinternational.org\",\n            \"religionnews.com\",\n            \"religioustolerance.org\",\n            \"renminbao.com\",\n            \"renyurenquan.org\",\n            \"rerouted.org\",\n            \"research.google\",\n            \"resilio.com\",\n            \"resistchina.org\",\n            \"retweeteffect.com\",\n            \"retweetist.com\",\n            \"retweetrank.com\",\n            \"reuters.com\",\n            \"reutersmedia.net\",\n            \"revleft.com\",\n            \"revocationcheck.com\",\n            \"revver.com\",\n            \"rfa.org\",\n            \"rfachina.com\",\n            \"rfamobile.org\",\n            \"rfaweb.org\",\n            \"rferl.org\",\n            \"rfi.fr\",\n            \"rfi.my\",\n            \"rightbtc.com\",\n            \"rightster.com\",\n            \"rigpa.org\",\n            \"riku.me\",\n            \"rileyguide.com\",\n            \"riseup.net\",\n            \"ritouki.jp\",\n            \"ritter.vg\",\n            \"rixcloud.com\",\n            \"rixcloud.us\",\n            \"rlwlw.com\",\n            \"rmjdw.com\",\n            \"rmjdw132.info\",\n            \"roadshow.hk\",\n            \"roboforex.com\",\n            \"robustnessiskey.com\",\n            \"rocket-inc.net\",\n            \"rocketbbs.com\",\n            \"rocksdb.org\",\n            \"rojo.com\",\n            \"rolfoundation.org\",\n            \"rolia.net\",\n            \"rolsociety.org\",\n            \"ronjoneswriter.com\",\n            \"roodo.com\",\n            \"rosechina.net\",\n            \"rotten.com\",\n            \"rsdlmonitor.com\",\n            \"rsf-chinese.org\",\n            \"rsf.org\",\n            \"rsgamen.org\",\n            \"rsshub.app\",\n            \"rssing.com\",\n            \"rssmeme.com\",\n            \"rtalabel.org\",\n            \"rthk.hk\",\n            \"rthk.org.hk\",\n            \"rti.org.tw\",\n            \"rti.tw\",\n            \"rtycminnesota.org\",\n            \"ruanyifeng.com\",\n            \"rukor.org\",\n            \"rule34.xxx\",\n            \"runbtx.com\",\n            \"rushbee.com\",\n            \"rusvpn.com\",\n            \"ruten.com.tw\",\n            \"rutracker.net\",\n            \"rutube.ru\",\n            \"ruyiseek.com\",\n            \"rxhj.net\",\n            \"s-cute.com\",\n            \"s-dragon.org\",\n            \"s1heng.com\",\n            \"s1s1s1.com\",\n            \"s4miniarchive.com\",\n            \"s8forum.com\",\n            \"sa.com\",\n            \"saboom.com\",\n            \"sacks.com\",\n            \"sacom.hk\",\n            \"sadistic-v.com\",\n            \"sadpanda.us\",\n            \"safechat.com\",\n            \"safeguarddefenders.com\",\n            \"safervpn.com\",\n            \"safety.google\",\n            \"saintyculture.com\",\n            \"saiq.me\",\n            \"sakuralive.com\",\n            \"sakya.org\",\n            \"salvation.org.hk\",\n            \"samair.ru\",\n            \"sambhota.org\",\n            \"sandscotaicentral.com\",\n            \"sankei.com\",\n            \"sanmin.com.tw\",\n            \"sans.edu\",\n            \"sapikachu.net\",\n            \"saveliuxiaobo.com\",\n            \"savemedia.com\",\n            \"savethedate.foo\",\n            \"savethesounds.info\",\n            \"savetibet.de\",\n            \"savetibet.fr\",\n            \"savetibet.nl\",\n            \"savetibet.org\",\n            \"savetibet.ru\",\n            \"savetibetstore.org\",\n            \"saveuighur.org\",\n            \"savevid.com\",\n            \"say2.info\",\n            \"sbme.me\",\n            \"sbs.com.au\",\n            \"scasino.com\",\n            \"schema.org\",\n            \"sciencemag.org\",\n            \"sciencenets.com\",\n            \"scieron.com\",\n            \"scmp.com\",\n            \"scmpchinese.com\",\n            \"scramble.io\",\n            \"scribd.com\",\n            \"scriptspot.com\",\n            \"search.com\",\n            \"search.xxx\",\n            \"searchtruth.com\",\n            \"searx.me\",\n            \"seatguru.com\",\n            \"seattlefdc.com\",\n            \"secretchina.com\",\n            \"secretgarden.no\",\n            \"secretsline.biz\",\n            \"secureservercdn.net\",\n            \"securetunnel.com\",\n            \"securityinabox.org\",\n            \"securitykiss.com\",\n            \"seed4.me\",\n            \"seehua.com\",\n            \"seesmic.com\",\n            \"seevpn.com\",\n            \"seezone.net\",\n            \"sejie.com\",\n            \"sellclassics.com\",\n            \"sendsmtp.com\",\n            \"sendspace.com\",\n            \"sensortower.com\",\n            \"seraph.me\",\n            \"servehttp.com\",\n            \"serveuser.com\",\n            \"serveusers.com\",\n            \"sesawe.net\",\n            \"sesawe.org\",\n            \"sethwklein.net\",\n            \"setn.com\",\n            \"settv.com.tw\",\n            \"setty.com.tw\",\n            \"sevenload.com\",\n            \"sex-11.com\",\n            \"sex.com\",\n            \"sex3.com\",\n            \"sex8.cc\",\n            \"sexandsubmission.com\",\n            \"sexbot.com\",\n            \"sexhu.com\",\n            \"sexhuang.com\",\n            \"sexidude.com\",\n            \"sexinsex.net\",\n            \"sextvx.com\",\n            \"sexxxy.biz\",\n            \"sf.net\",\n            \"sfileydy.com\",\n            \"sfshibao.com\",\n            \"sftindia.org\",\n            \"sftuk.org\",\n            \"shadeyouvpn.com\",\n            \"shadow.ma\",\n            \"shadowsky.xyz\",\n            \"shadowsocks-r.com\",\n            \"shadowsocks.asia\",\n            \"shadowsocks.be\",\n            \"shadowsocks.com\",\n            \"shadowsocks.com.hk\",\n            \"shadowsocks.org\",\n            \"shadowsocks9.com\",\n            \"shafaqna.com\",\n            \"shahit.biz\",\n            \"shambalapost.com\",\n            \"shambhalasun.com\",\n            \"shangfang.org\",\n            \"shapeservices.com\",\n            \"sharebee.com\",\n            \"sharecool.org\",\n            \"sharpdaily.com.hk\",\n            \"sharpdaily.hk\",\n            \"sharpdaily.tw\",\n            \"shat-tibet.com\",\n            \"shattered.io\",\n            \"sheikyermami.com\",\n            \"shellfire.de\",\n            \"shemalez.com\",\n            \"shenshou.org\",\n            \"shenyun.com\",\n            \"shenyunperformingarts.org\",\n            \"shenyunshop.com\",\n            \"shenzhoufilm.com\",\n            \"shenzhouzhengdao.org\",\n            \"sherabgyaltsen.com\",\n            \"shiatv.net\",\n            \"shicheng.org\",\n            \"shiksha.com\",\n            \"shinychan.com\",\n            \"shipcamouflage.com\",\n            \"shireyishunjian.com\",\n            \"shitaotv.org\",\n            \"shixiao.org\",\n            \"shizhao.org\",\n            \"shkspr.mobi\",\n            \"shodanhq.com\",\n            \"shooshtime.com\",\n            \"shop2000.com.tw\",\n            \"shopee.tw\",\n            \"shopping.com\",\n            \"showhaotu.com\",\n            \"showtime.jp\",\n            \"showwe.tw\",\n            \"shutterstock.com\",\n            \"shvoong.com\",\n            \"shwchurch.org\",\n            \"shwchurch3.com\",\n            \"siddharthasintent.org\",\n            \"sidelinesnews.com\",\n            \"sidelinessportseatery.com\",\n            \"sierrafriendsoftibet.org\",\n            \"signal.org\",\n            \"sijihuisuo.club\",\n            \"sijihuisuo.com\",\n            \"silkbook.com\",\n            \"simbolostwitter.com\",\n            \"simplecd.org\",\n            \"simpleproductivityblog.com\",\n            \"sina.com\",\n            \"sina.com.hk\",\n            \"sina.com.tw\",\n            \"sinchew.com.my\",\n            \"singaporepools.com.sg\",\n            \"singfortibet.com\",\n            \"singpao.com.hk\",\n            \"singtao.ca\",\n            \"singtao.com\",\n            \"singtaousa.com\",\n            \"sino-monthly.com\",\n            \"sinoants.com\",\n            \"sinoca.com\",\n            \"sinocast.com\",\n            \"sinocism.com\",\n            \"sinoinsider.com\",\n            \"sinomontreal.ca\",\n            \"sinonet.ca\",\n            \"sinopitt.info\",\n            \"sinoquebec.com\",\n            \"sipml5.org\",\n            \"sis.xxx\",\n            \"sis001.com\",\n            \"sis001.us\",\n            \"site2unblock.com\",\n            \"site90.net\",\n            \"sitebro.tw\",\n            \"sitekreator.com\",\n            \"sitemaps.org\",\n            \"six-degrees.io\",\n            \"sixth.biz\",\n            \"sjrt.org\",\n            \"sjum.cn\",\n            \"sketchappsources.com\",\n            \"skimtube.com\",\n            \"skk.moe\",\n            \"skybet.com\",\n            \"skyking.com.tw\",\n            \"skykiwi.com\",\n            \"skynet.be\",\n            \"skype.com\",\n            \"skyvegas.com\",\n            \"skyxvpn.com\",\n            \"slacker.com\",\n            \"slandr.net\",\n            \"slaytizle.com\",\n            \"sleazydream.com\",\n            \"slheng.com\",\n            \"slickvpn.com\",\n            \"slideshare.net\",\n            \"slime.com.tw\",\n            \"slinkset.com\",\n            \"slutload.com\",\n            \"slutmoonbeam.com\",\n            \"slyip.com\",\n            \"slyip.net\",\n            \"sm-miracle.com\",\n            \"smartdnsproxy.com\",\n            \"smarthide.com\",\n            \"smartmailcloud.com\",\n            \"smchbooks.com\",\n            \"smh.com.au\",\n            \"smhric.org\",\n            \"smith.edu\",\n            \"smyxy.org\",\n            \"snapchat.com\",\n            \"snaptu.com\",\n            \"sndcdn.com\",\n            \"sneakme.net\",\n            \"snowlionpub.com\",\n            \"so-net.net.tw\",\n            \"sobees.com\",\n            \"soc.mil\",\n            \"socialblade.com\",\n            \"socialwhale.com\",\n            \"socks-proxy.net\",\n            \"sockscap64.com\",\n            \"sockslist.net\",\n            \"socrec.org\",\n            \"sod.co.jp\",\n            \"softether-download.com\",\n            \"softether.co.jp\",\n            \"softether.org\",\n            \"softfamous.com\",\n            \"softlayer.net\",\n            \"softnology.biz\",\n            \"softsmirror.cf\",\n            \"softwarebychuck.com\",\n            \"sogclub.com\",\n            \"sogoo.org\",\n            \"sogrady.me\",\n            \"soh.tw\",\n            \"sohcradio.com\",\n            \"sohfrance.org\",\n            \"soifind.com\",\n            \"sokamonline.com\",\n            \"sokmil.com\",\n            \"solana.com\",\n            \"solidaritetibet.org\",\n            \"solidfiles.com\",\n            \"solv.finance\",\n            \"somee.com\",\n            \"songjianjun.com\",\n            \"sonicbbs.cc\",\n            \"sonidodelaesperanza.org\",\n            \"sopcast.com\",\n            \"sopcast.org\",\n            \"sophos.com\",\n            \"sorazone.net\",\n            \"sorting-algorithms.com\",\n            \"sos.org\",\n            \"sosreader.com\",\n            \"sostibet.org\",\n            \"sou-tong.org\",\n            \"soubory.com\",\n            \"soul-plus.net\",\n            \"soulcaliburhentai.net\",\n            \"soumo.info\",\n            \"soundcloud.com\",\n            \"soundofhope.kr\",\n            \"soundofhope.org\",\n            \"soup.io\",\n            \"soupofmedia.com\",\n            \"sourceforge.net\",\n            \"sourcewadio.com\",\n            \"south-plus.org\",\n            \"southnews.com.tw\",\n            \"sowers.org.hk\",\n            \"sowiki.net\",\n            \"soylent.com\",\n            \"soylentnews.org\",\n            \"spankbang.com\",\n            \"spankingtube.com\",\n            \"spankwire.com\",\n            \"spb.com\",\n            \"speakerdeck.com\",\n            \"speedify.com\",\n            \"spem.at\",\n            \"spencertipping.com\",\n            \"spendee.com\",\n            \"spicevpn.com\",\n            \"spideroak.com\",\n            \"spike.com\",\n            \"spotflux.com\",\n            \"spotify.com\",\n            \"spreadshirt.es\",\n            \"spring4u.info\",\n            \"springboardplatform.com\",\n            \"sprite.org\",\n            \"sproutcore.com\",\n            \"sproxy.info\",\n            \"squirly.info\",\n            \"squirrelvpn.com\",\n            \"srocket.us\",\n            \"ss-link.com\",\n            \"ssglobal.co\",\n            \"ssglobal.me\",\n            \"ssh91.com\",\n            \"ssl443.org\",\n            \"sspanel.net\",\n            \"sspro.ml\",\n            \"ssr.tools\",\n            \"ssrshare.com\",\n            \"sss.camp\",\n            \"sstm.moe\",\n            \"sstmlt.moe\",\n            \"sstmlt.net\",\n            \"stackoverflow.com\",\n            \"stage64.hk\",\n            \"standupfortibet.org\",\n            \"standwithhk.org\",\n            \"stanford.edu\",\n            \"starfishfx.com\",\n            \"starp2p.com\",\n            \"startpage.com\",\n            \"startuplivingchina.com\",\n            \"stat.gov.tw\",\n            \"state.gov\",\n            \"static-economist.com\",\n            \"staticflickr.com\",\n            \"statueofdemocracy.org\",\n            \"stboy.net\",\n            \"stc.com.sa\",\n            \"steamcommunity.com\",\n            \"steampowered.com\",\n            \"steel-storm.com\",\n            \"steemit.com\",\n            \"steganos.com\",\n            \"steganos.net\",\n            \"stepchina.com\",\n            \"stephaniered.com\",\n            \"stgloballink.com\",\n            \"stheadline.com\",\n            \"sthoo.com\",\n            \"stickam.com\",\n            \"stickeraction.com\",\n            \"stileproject.com\",\n            \"sto.cc\",\n            \"stoporganharvesting.org\",\n            \"stoptibetcrisis.net\",\n            \"storagenewsletter.com\",\n            \"stories.google\",\n            \"storify.com\",\n            \"storm.mg\",\n            \"stormmediagroup.com\",\n            \"stoweboyd.com\",\n            \"straitstimes.com\",\n            \"stranabg.com\",\n            \"straplessdildo.com\",\n            \"streamable.com\",\n            \"streamate.com\",\n            \"streamingthe.net\",\n            \"streema.com\",\n            \"streetvoice.com\",\n            \"strikingly.com\",\n            \"strongvpn.com\",\n            \"strongwindpress.com\",\n            \"student.tw\",\n            \"studentsforafreetibet.org\",\n            \"stumbleupon.com\",\n            \"stupidvideos.com\",\n            \"substack.com\",\n            \"successfn.com\",\n            \"sueddeutsche.de\",\n            \"sugarsync.com\",\n            \"sugobbs.com\",\n            \"sugumiru18.com\",\n            \"suissl.com\",\n            \"sulian.me\",\n            \"summify.com\",\n            \"sumrando.com\",\n            \"sun1911.com\",\n            \"sundayguardianlive.com\",\n            \"sunmedia.ca\",\n            \"sunporno.com\",\n            \"sunskyforum.com\",\n            \"sunta.com.tw\",\n            \"sunvpn.net\",\n            \"suoluo.org\",\n            \"supchina.com\",\n            \"superfreevpn.com\",\n            \"superokayama.com\",\n            \"superpages.com\",\n            \"supervpn.net\",\n            \"superzooi.com\",\n            \"suppig.net\",\n            \"suprememastertv.com\",\n            \"surfeasy.com\",\n            \"surfeasy.com.au\",\n            \"surfshark.com\",\n            \"suroot.com\",\n            \"surrenderat20.net\",\n            \"sustainability.google\",\n            \"svsfx.com\",\n            \"swagbucks.com\",\n            \"swissinfo.ch\",\n            \"swissvpn.net\",\n            \"switch1.jp\",\n            \"switchvpn.net\",\n            \"sydneytoday.com\",\n            \"sylfoundation.org\",\n            \"syncback.com\",\n            \"synergyse.com\",\n            \"sysresccd.org\",\n            \"sytes.net\",\n            \"syx86.cn\",\n            \"syx86.com\",\n            \"szbbs.net\",\n            \"szetowah.org.hk\",\n            \"t-g.com\",\n            \"t.co\",\n            \"t.me\",\n            \"t35.com\",\n            \"t66y.com\",\n            \"t91y.com\",\n            \"taa-usa.org\",\n            \"taaze.tw\",\n            \"tablesgenerator.com\",\n            \"tabtter.jp\",\n            \"tacem.org\",\n            \"taconet.com.tw\",\n            \"taedp.org.tw\",\n            \"tafm.org\",\n            \"tagwa.org.au\",\n            \"tagwalk.com\",\n            \"tahr.org.tw\",\n            \"taipei.gov.tw\",\n            \"taipeisociety.org\",\n            \"taipeitimes.com\",\n            \"taiwan-sex.com\",\n            \"taiwanbible.com\",\n            \"taiwancon.com\",\n            \"taiwandaily.net\",\n            \"taiwandc.org\",\n            \"taiwanhot.net\",\n            \"taiwanjobs.gov.tw\",\n            \"taiwanjustice.com\",\n            \"taiwanjustice.net\",\n            \"taiwankiss.com\",\n            \"taiwannation.com\",\n            \"taiwannation.com.tw\",\n            \"taiwanncf.org.tw\",\n            \"taiwannews.com.tw\",\n            \"taiwanonline.cc\",\n            \"taiwantp.net\",\n            \"taiwantt.org.tw\",\n            \"taiwanus.net\",\n            \"taiwanyes.com\",\n            \"talk853.com\",\n            \"talkboxapp.com\",\n            \"talkcc.com\",\n            \"talkonly.net\",\n            \"tamiaode.tk\",\n            \"tampabay.com\",\n            \"tanc.org\",\n            \"tangben.com\",\n            \"tangren.us\",\n            \"taoism.net\",\n            \"taolun.info\",\n            \"tapanwap.com\",\n            \"tapatalk.com\",\n            \"taragana.com\",\n            \"target.com\",\n            \"tascn.com.au\",\n            \"taup.net\",\n            \"taup.org.tw\",\n            \"taweet.com\",\n            \"tbcollege.org\",\n            \"tbi.org.hk\",\n            \"tbicn.org\",\n            \"tbjyt.org\",\n            \"tbpic.info\",\n            \"tbrc.org\",\n            \"tbs-rainbow.org\",\n            \"tbsec.org\",\n            \"tbsmalaysia.org\",\n            \"tbsn.org\",\n            \"tbsseattle.org\",\n            \"tbssqh.org\",\n            \"tbswd.org\",\n            \"tbtemple.org.uk\",\n            \"tbthouston.org\",\n            \"tccwonline.org\",\n            \"tcewf.org\",\n            \"tchrd.org\",\n            \"tcnynj.org\",\n            \"tcpspeed.co\",\n            \"tcpspeed.com\",\n            \"tcsofbc.org\",\n            \"tcsovi.org\",\n            \"tdesktop.com\",\n            \"tdm.com.mo\",\n            \"teachparentstech.org\",\n            \"teamamericany.com\",\n            \"technews.tw\",\n            \"techspot.com\",\n            \"techviz.net\",\n            \"teck.in\",\n            \"teco-hk.org\",\n            \"teco-mo.org\",\n            \"teddysun.com\",\n            \"teeniefuck.net\",\n            \"teensinasia.com\",\n            \"tehrantimes.com\",\n            \"telecomspace.com\",\n            \"telegra.ph\",\n            \"telegram.dog\",\n            \"telegram.me\",\n            \"telegram.org\",\n            \"telegramdownload.com\",\n            \"telegraph.co.uk\",\n            \"telesco.pe\",\n            \"tellme.pw\",\n            \"tenacy.com\",\n            \"tensorflow.org\",\n            \"tenzinpalmo.com\",\n            \"terabox.com\",\n            \"tew.org\",\n            \"textnow.me\",\n            \"tfhub.dev\",\n            \"tfiflve.com\",\n            \"thaicn.com\",\n            \"thb.gov.tw\",\n            \"theatlantic.com\",\n            \"theatrum-belli.com\",\n            \"theaustralian.com.au\",\n            \"thebcomplex.com\",\n            \"theblaze.com\",\n            \"theblemish.com\",\n            \"thebobs.com\",\n            \"thebodyshop-usa.com\",\n            \"thechinabeat.org\",\n            \"thechinacollection.org\",\n            \"thechinastory.org\",\n            \"theconversation.com\",\n            \"thedalailamamovie.com\",\n            \"thediplomat.com\",\n            \"thedw.us\",\n            \"theepochtimes.com\",\n            \"thefacebook.com\",\n            \"thefrontier.hk\",\n            \"thegay.com\",\n            \"thegioitinhoc.vn\",\n            \"thegly.com\",\n            \"theguardian.com\",\n            \"thehots.info\",\n            \"thehousenews.com\",\n            \"thehun.net\",\n            \"theinitium.com\",\n            \"themoviedb.org\",\n            \"thenewslens.com\",\n            \"thepiratebay.org\",\n            \"theporndude.com\",\n            \"theportalwiki.com\",\n            \"theprint.in\",\n            \"thereallove.kr\",\n            \"therock.net.nz\",\n            \"thesaturdaypaper.com.au\",\n            \"thestandnews.com\",\n            \"thetibetcenter.org\",\n            \"thetibetconnection.org\",\n            \"thetibetmuseum.org\",\n            \"thetibetpost.com\",\n            \"thetinhat.com\",\n            \"thetrotskymovie.com\",\n            \"thetvdb.com\",\n            \"thevivekspot.com\",\n            \"thewgo.org\",\n            \"theync.com\",\n            \"thinkgeek.com\",\n            \"thinkingtaiwan.com\",\n            \"thinkwithgoogle.com\",\n            \"thisav.com\",\n            \"thlib.org\",\n            \"thomasbernhard.org\",\n            \"thongdreams.com\",\n            \"threatchaos.com\",\n            \"throughnightsfire.com\",\n            \"thumbzilla.com\",\n            \"thywords.com\",\n            \"thywords.com.tw\",\n            \"tiananmenduizhi.com\",\n            \"tiananmenmother.org\",\n            \"tiananmenuniv.com\",\n            \"tiananmenuniv.net\",\n            \"tiandixing.org\",\n            \"tianhuayuan.com\",\n            \"tianlawoffice.com\",\n            \"tianti.io\",\n            \"tiantibooks.org\",\n            \"tianyantong.org.cn\",\n            \"tianzhu.org\",\n            \"tibet-envoy.eu\",\n            \"tibet-foundation.org\",\n            \"tibet-house-trust.co.uk\",\n            \"tibet-initiative.de\",\n            \"tibet-munich.de\",\n            \"tibet.a.se\",\n            \"tibet.at\",\n            \"tibet.ca\",\n            \"tibet.com\",\n            \"tibet.fr\",\n            \"tibet.net\",\n            \"tibet.nu\",\n            \"tibet.org\",\n            \"tibet.org.tw\",\n            \"tibet.sk\",\n            \"tibet.to\",\n            \"tibet3rdpole.org\",\n            \"tibetaction.net\",\n            \"tibetaid.org\",\n            \"tibetalk.com\",\n            \"tibetan-alliance.org\",\n            \"tibetan.fr\",\n            \"tibetanaidproject.org\",\n            \"tibetanarts.org\",\n            \"tibetanbuddhistinstitute.org\",\n            \"tibetancommunity.org\",\n            \"tibetancommunityuk.net\",\n            \"tibetanculture.org\",\n            \"tibetanentrepreneurs.org\",\n            \"tibetanfeministcollective.org\",\n            \"tibetanhealth.org\",\n            \"tibetanjournal.com\",\n            \"tibetanlanguage.org\",\n            \"tibetanliberation.org\",\n            \"tibetanpaintings.com\",\n            \"tibetanphotoproject.com\",\n            \"tibetanpoliticalreview.org\",\n            \"tibetanreview.net\",\n            \"tibetansports.org\",\n            \"tibetanwomen.org\",\n            \"tibetanyouth.org\",\n            \"tibetanyouthcongress.org\",\n            \"tibetcharity.dk\",\n            \"tibetcharity.in\",\n            \"tibetchild.org\",\n            \"tibetcity.com\",\n            \"tibetcollection.com\",\n            \"tibetcorps.org\",\n            \"tibetexpress.net\",\n            \"tibetfocus.com\",\n            \"tibetfund.org\",\n            \"tibetgermany.com\",\n            \"tibetgermany.de\",\n            \"tibethaus.com\",\n            \"tibetheritagefund.org\",\n            \"tibethouse.jp\",\n            \"tibethouse.org\",\n            \"tibethouse.us\",\n            \"tibetinfonet.net\",\n            \"tibetjustice.org\",\n            \"tibetkomite.dk\",\n            \"tibetmuseum.org\",\n            \"tibetnetwork.org\",\n            \"tibetoffice.ch\",\n            \"tibetoffice.com.au\",\n            \"tibetoffice.eu\",\n            \"tibetoffice.org\",\n            \"tibetonline.com\",\n            \"tibetonline.tv\",\n            \"tibetoralhistory.org\",\n            \"tibetpolicy.eu\",\n            \"tibetrelieffund.co.uk\",\n            \"tibetsites.com\",\n            \"tibetsociety.com\",\n            \"tibetsun.com\",\n            \"tibetsupportgroup.org\",\n            \"tibetswiss.ch\",\n            \"tibettelegraph.com\",\n            \"tibettimes.net\",\n            \"tibetwrites.org\",\n            \"ticket.com.tw\",\n            \"tigervpn.com\",\n            \"tiktok.com\",\n            \"tiltbrush.com\",\n            \"timdir.com\",\n            \"time.com\",\n            \"timesnownews.com\",\n            \"timsah.com\",\n            \"timtales.com\",\n            \"tinc-vpn.org\",\n            \"tiney.com\",\n            \"tineye.com\",\n            \"tintuc101.com\",\n            \"tiny.cc\",\n            \"tinychat.com\",\n            \"tinypaste.com\",\n            \"tipas.net\",\n            \"tipo.gov.tw\",\n            \"tistory.com\",\n            \"tkcs-collins.com\",\n            \"tl.gd\",\n            \"tma.co.jp\",\n            \"tmagazine.com\",\n            \"tmdfish.com\",\n            \"tmi.me\",\n            \"tmpp.org\",\n            \"tnaflix.com\",\n            \"tngrnow.com\",\n            \"tngrnow.net\",\n            \"tnp.org\",\n            \"to-porno.com\",\n            \"togetter.com\",\n            \"toh.info\",\n            \"tokyo-247.com\",\n            \"tokyo-hot.com\",\n            \"tokyo-porn-tube.com\",\n            \"tokyocn.com\",\n            \"tomonews.net\",\n            \"tongil.or.kr\",\n            \"tono-oka.jp\",\n            \"tonyyan.net\",\n            \"toodoc.com\",\n            \"toonel.net\",\n            \"top.tv\",\n            \"top10vpn.com\",\n            \"top81.ws\",\n            \"topbtc.com\",\n            \"topnews.in\",\n            \"toppornsites.com\",\n            \"topshareware.com\",\n            \"topsy.com\",\n            \"toptip.ca\",\n            \"tora.to\",\n            \"torcn.com\",\n            \"torguard.net\",\n            \"torlock.com\",\n            \"torproject.org\",\n            \"torrentkitty.tv\",\n            \"torrentprivacy.com\",\n            \"torrentproject.se\",\n            \"torrenty.org\",\n            \"torrentz.eu\",\n            \"torvpn.com\",\n            \"totalvpn.com\",\n            \"toutiaoabc.com\",\n            \"towngain.com\",\n            \"toypark.in\",\n            \"toythieves.com\",\n            \"toytractorshow.com\",\n            \"tparents.org\",\n            \"tpi.org.tw\",\n            \"tracfone.com\",\n            \"tradingview.com\",\n            \"translate.goog\",\n            \"translate.google\",\n            \"transparency.org\",\n            \"treemall.com.tw\",\n            \"trendsmap.com\",\n            \"trialofccp.org\",\n            \"trickip.net\",\n            \"trickip.org\",\n            \"trimondi.de\",\n            \"tronscan.org\",\n            \"trouw.nl\",\n            \"trt.net.tr\",\n            \"trtc.com.tw\",\n            \"truebuddha-md.org\",\n            \"trulyergonomic.com\",\n            \"truthontour.org\",\n            \"truthsocial.com\",\n            \"truveo.com\",\n            \"tryheart.jp\",\n            \"tsctv.net\",\n            \"tsemtulku.com\",\n            \"tsquare.tv\",\n            \"tsu.org.tw\",\n            \"tsunagarumon.com\",\n            \"tt1069.com\",\n            \"tttan.com\",\n            \"ttv.com.tw\",\n            \"ttvnw.net\",\n            \"tu8964.com\",\n            \"tubaholic.com\",\n            \"tube.com\",\n            \"tube8.com\",\n            \"tube911.com\",\n            \"tubecup.com\",\n            \"tubegals.com\",\n            \"tubeislam.com\",\n            \"tubepornclassic.com\",\n            \"tubestack.com\",\n            \"tubewolf.com\",\n            \"tuibeitu.net\",\n            \"tuidang.net\",\n            \"tuidang.org\",\n            \"tuidang.se\",\n            \"tuitui.info\",\n            \"tuitwit.com\",\n            \"tumblr.com\",\n            \"tumutanzi.com\",\n            \"tumview.com\",\n            \"tunein.com\",\n            \"tunnelbear.com\",\n            \"tunnelblick.net\",\n            \"tunnelr.com\",\n            \"tunsafe.com\",\n            \"turansam.org\",\n            \"turbobit.net\",\n            \"turbohide.com\",\n            \"turbotwitter.com\",\n            \"turkistantimes.com\",\n            \"turntable.fm\",\n            \"tushycash.com\",\n            \"tutanota.com\",\n            \"tuvpn.com\",\n            \"tuzaijidi.com\",\n            \"tv.com\",\n            \"tv.google\",\n            \"tvants.com\",\n            \"tvb.com\",\n            \"tvboxnow.com\",\n            \"tvbs.com.tw\",\n            \"tvider.com\",\n            \"tvmost.com.hk\",\n            \"tvplayvideos.com\",\n            \"tvunetworks.com\",\n            \"tw-blog.com\",\n            \"tw-npo.org\",\n            \"tw01.org\",\n            \"twaitter.com\",\n            \"twapperkeeper.com\",\n            \"twaud.io\",\n            \"twavi.com\",\n            \"twbbs.net.tw\",\n            \"twbbs.org\",\n            \"twbbs.tw\",\n            \"twblogger.com\",\n            \"tweepguide.com\",\n            \"tweeplike.me\",\n            \"tweepmag.com\",\n            \"tweepml.org\",\n            \"tweetbackup.com\",\n            \"tweetboard.com\",\n            \"tweetboner.biz\",\n            \"tweetcs.com\",\n            \"tweetdeck.com\",\n            \"tweetedtimes.com\",\n            \"tweetmylast.fm\",\n            \"tweetphoto.com\",\n            \"tweetrans.com\",\n            \"tweetree.com\",\n            \"tweettunnel.com\",\n            \"tweetwally.com\",\n            \"tweetymail.com\",\n            \"tweez.net\",\n            \"twelve.today\",\n            \"twerkingbutt.com\",\n            \"twftp.org\",\n            \"twgreatdaily.com\",\n            \"twibase.com\",\n            \"twibble.de\",\n            \"twibbon.com\",\n            \"twibs.com\",\n            \"twicountry.org\",\n            \"twicsy.com\",\n            \"twiends.com\",\n            \"twifan.com\",\n            \"twiffo.com\",\n            \"twiggit.org\",\n            \"twilightsex.com\",\n            \"twilio.com\",\n            \"twilog.org\",\n            \"twimbow.com\",\n            \"twimg.com\",\n            \"twindexx.com\",\n            \"twip.me\",\n            \"twipple.jp\",\n            \"twishort.com\",\n            \"twistar.cc\",\n            \"twister.net.co\",\n            \"twisterio.com\",\n            \"twisternow.com\",\n            \"twistory.net\",\n            \"twit2d.com\",\n            \"twitbrowser.net\",\n            \"twitcause.com\",\n            \"twitch.tv\",\n            \"twitchcdn.net\",\n            \"twitgether.com\",\n            \"twitgoo.com\",\n            \"twitiq.com\",\n            \"twitlonger.com\",\n            \"twitmania.com\",\n            \"twitoaster.com\",\n            \"twitonmsn.com\",\n            \"twitpic.com\",\n            \"twitstat.com\",\n            \"twittbot.net\",\n            \"twitter.com\",\n            \"twitter.jp\",\n            \"twitter4j.org\",\n            \"twittercounter.com\",\n            \"twitterfeed.com\",\n            \"twittergadget.com\",\n            \"twitterkr.com\",\n            \"twittermail.com\",\n            \"twitterrific.com\",\n            \"twittertim.es\",\n            \"twitthat.com\",\n            \"twitturk.com\",\n            \"twitturly.com\",\n            \"twitvid.com\",\n            \"twitzap.com\",\n            \"twiyia.com\",\n            \"twnorth.org.tw\",\n            \"twreporter.org\",\n            \"twskype.com\",\n            \"twstar.net\",\n            \"twt.tl\",\n            \"twtkr.com\",\n            \"twtrland.com\",\n            \"twttr.com\",\n            \"twurl.nl\",\n            \"twyac.org\",\n            \"txxx.com\",\n            \"tycool.com\",\n            \"typepad.com\",\n            \"typora.io\",\n            \"u15.info\",\n            \"u9un.com\",\n            \"ub0.cc\",\n            \"ubddns.org\",\n            \"uberproxy.net\",\n            \"uc-japan.org\",\n            \"ucam.org\",\n            \"ucanews.com\",\n            \"ucdc1998.org\",\n            \"uchicago.edu\",\n            \"uderzo.it\",\n            \"udn.com\",\n            \"udn.com.tw\",\n            \"udnbkk.com\",\n            \"uforadio.com.tw\",\n            \"ufreevpn.com\",\n            \"ugo.com\",\n            \"uhdwallpapers.org\",\n            \"uhrp.org\",\n            \"uighur.nl\",\n            \"uighurbiz.net\",\n            \"uk.to\",\n            \"ukcdp.co.uk\",\n            \"ukliferadio.co.uk\",\n            \"uku.im\",\n            \"ulike.net\",\n            \"ulop.net\",\n            \"ultravpn.fr\",\n            \"ultraxs.com\",\n            \"umich.edu\",\n            \"unblock-us.com\",\n            \"unblockdmm.com\",\n            \"unblocker.yt\",\n            \"unblocksit.es\",\n            \"uncyclomedia.org\",\n            \"uncyclopedia.hk\",\n            \"uncyclopedia.tw\",\n            \"underwoodammo.com\",\n            \"unholyknight.com\",\n            \"uni.cc\",\n            \"unicode.org\",\n            \"unification.net\",\n            \"unification.org.tw\",\n            \"unirule.cloud\",\n            \"unitedsocialpress.com\",\n            \"unix100.com\",\n            \"unknownspace.org\",\n            \"unodedos.com\",\n            \"unpo.org\",\n            \"unseen.is\",\n            \"unstable.icu\",\n            \"untraceable.us\",\n            \"uocn.org\",\n            \"updatestar.com\",\n            \"upghsbc.com\",\n            \"upholdjustice.org\",\n            \"upload4u.info\",\n            \"uploaded.net\",\n            \"uploaded.to\",\n            \"uploadstation.com\",\n            \"upmedia.mg\",\n            \"upornia.com\",\n            \"uproxy.org\",\n            \"uptodown.com\",\n            \"upwill.org\",\n            \"ur7s.com\",\n            \"uraban.me\",\n            \"urbandictionary.com\",\n            \"urbansurvival.com\",\n            \"urchin.com\",\n            \"url.com.tw\",\n            \"url.tw\",\n            \"urlborg.com\",\n            \"urlparser.com\",\n            \"us.to\",\n            \"usacn.com\",\n            \"usaip.eu\",\n            \"usc.edu\",\n            \"uscnpm.org\",\n            \"usembassy.gov\",\n            \"usfk.mil\",\n            \"usma.edu\",\n            \"usmc.mil\",\n            \"usocctn.com\",\n            \"uspto.gov\",\n            \"ustibetcommittee.org\",\n            \"ustream.tv\",\n            \"usus.cc\",\n            \"utopianpal.com\",\n            \"uu-gg.com\",\n            \"uukanshu.com\",\n            \"uvwxyz.xyz\",\n            \"uwants.com\",\n            \"uwants.net\",\n            \"uyghur-j.org\",\n            \"uyghur.co.uk\",\n            \"uyghuraa.org\",\n            \"uyghuramerican.org\",\n            \"uyghurbiz.org\",\n            \"uyghurcanadian.ca\",\n            \"uyghurcongress.org\",\n            \"uyghurpen.org\",\n            \"uyghurpress.com\",\n            \"uyghurstudies.org\",\n            \"uyghurtribunal.com\",\n            \"uygur.org\",\n            \"uymaarip.com\",\n            \"v2ex.com\",\n            \"v2fly.org\",\n            \"v2ray.com\",\n            \"v2raycn.com\",\n            \"v2raytech.com\",\n            \"valeursactuelles.com\",\n            \"van001.com\",\n            \"van698.com\",\n            \"vanemu.cn\",\n            \"vanilla-jp.com\",\n            \"vanpeople.com\",\n            \"vansky.com\",\n            \"vaticannews.va\",\n            \"vatn.org\",\n            \"vcf-online.org\",\n            \"vcfbuilder.org\",\n            \"vegasred.com\",\n            \"velkaepocha.sk\",\n            \"venbbs.com\",\n            \"venchina.com\",\n            \"venetianmacao.com\",\n            \"ventureswell.com\",\n            \"veoh.com\",\n            \"vercel.app\",\n            \"verizon.net\",\n            \"vermonttibet.org\",\n            \"versavpn.com\",\n            \"verybs.com\",\n            \"vevo.com\",\n            \"vft.com.tw\",\n            \"viber.com\",\n            \"vica.info\",\n            \"victimsofcommunism.org\",\n            \"vid.me\",\n            \"vidble.com\",\n            \"videobam.com\",\n            \"videodetective.com\",\n            \"videomega.tv\",\n            \"videomo.com\",\n            \"videopediaworld.com\",\n            \"videopress.com\",\n            \"vidinfo.org\",\n            \"vietdaikynguyen.com\",\n            \"vijayatemple.org\",\n            \"vilavpn.com\",\n            \"vimeo.com\",\n            \"vimperator.org\",\n            \"vincnd.com\",\n            \"vine.co\",\n            \"vinniev.com\",\n            \"vip-enterprise.com\",\n            \"virginia.edu\",\n            \"virtualrealporn.com\",\n            \"visibletweets.com\",\n            \"visiontimes.com\",\n            \"vital247.org\",\n            \"viu.com\",\n            \"viu.tv\",\n            \"vivahentai4u.net\",\n            \"vivaldi.com\",\n            \"vivatube.com\",\n            \"vivthomas.com\",\n            \"vizvaz.com\",\n            \"vjav.com\",\n            \"vjmedia.com.hk\",\n            \"vllcs.org\",\n            \"vmixcore.com\",\n            \"vmpsoft.com\",\n            \"vnet.link\",\n            \"voa.mobi\",\n            \"voacambodia.com\",\n            \"voacantonese.com\",\n            \"voachinese.com\",\n            \"voachineseblog.com\",\n            \"voagd.com\",\n            \"voaindonesia.com\",\n            \"voanews.com\",\n            \"voatibetan.com\",\n            \"voatibetanenglish.com\",\n            \"vocativ.com\",\n            \"vocn.tv\",\n            \"vocus.cc\",\n            \"voicettank.org\",\n            \"vot.org\",\n            \"vovo2000.com\",\n            \"voxer.com\",\n            \"voy.com\",\n            \"vpn.ac\",\n            \"vpn4all.com\",\n            \"vpnaccount.org\",\n            \"vpnaccounts.com\",\n            \"vpnbook.com\",\n            \"vpncomparison.org\",\n            \"vpncoupons.com\",\n            \"vpncup.com\",\n            \"vpndada.com\",\n            \"vpnfan.com\",\n            \"vpnfire.com\",\n            \"vpnfires.biz\",\n            \"vpnforgame.net\",\n            \"vpngate.jp\",\n            \"vpngate.net\",\n            \"vpngratis.net\",\n            \"vpnhq.com\",\n            \"vpnhub.com\",\n            \"vpninja.net\",\n            \"vpnintouch.com\",\n            \"vpnintouch.net\",\n            \"vpnjack.com\",\n            \"vpnmaster.com\",\n            \"vpnmentor.com\",\n            \"vpnpick.com\",\n            \"vpnpop.com\",\n            \"vpnpronet.com\",\n            \"vpnreactor.com\",\n            \"vpnreviewz.com\",\n            \"vpnsecure.me\",\n            \"vpnshazam.com\",\n            \"vpnshieldapp.com\",\n            \"vpnsp.com\",\n            \"vpntraffic.com\",\n            \"vpntunnel.com\",\n            \"vpnuk.info\",\n            \"vpnunlimitedapp.com\",\n            \"vpnvip.com\",\n            \"vpnworldwide.com\",\n            \"vporn.com\",\n            \"vpser.net\",\n            \"vraiesagesse.net\",\n            \"vrmtr.com\",\n            \"vrsmash.com\",\n            \"vs.com\",\n            \"vtunnel.com\",\n            \"vuku.cc\",\n            \"vultryhw.com\",\n            \"vzw.com\",\n            \"w3.org\",\n            \"w3schools.com\",\n            \"waffle1999.com\",\n            \"wahas.com\",\n            \"waigaobu.com\",\n            \"waikeung.org\",\n            \"wailaike.net\",\n            \"wainao.me\",\n            \"waiwaier.com\",\n            \"wallmama.com\",\n            \"wallornot.org\",\n            \"wallpapercasa.com\",\n            \"wallproxy.com\",\n            \"wallsttv.com\",\n            \"waltermartin.com\",\n            \"waltermartin.org\",\n            \"wan-press.org\",\n            \"wanderinghorse.net\",\n            \"wangafu.net\",\n            \"wangjinbo.org\",\n            \"wanglixiong.com\",\n            \"wango.org\",\n            \"wangruoshui.net\",\n            \"wangruowang.org\",\n            \"want-daily.com\",\n            \"wanz-factory.com\",\n            \"wapedia.mobi\",\n            \"warehouse333.com\",\n            \"warroom.org\",\n            \"waselpro.com\",\n            \"washeng.net\",\n            \"washingtonpost.com\",\n            \"watch8x.com\",\n            \"watchinese.com\",\n            \"watchmygf.net\",\n            \"watchout.tw\",\n            \"wattpad.com\",\n            \"wav.tv\",\n            \"waveprotocol.org\",\n            \"waymo.com\",\n            \"wda.gov.tw\",\n            \"wdf5.com\",\n            \"wealth.com.tw\",\n            \"wearehairy.com\",\n            \"wearn.com\",\n            \"weather.com.hk\",\n            \"web.dev\",\n            \"web2project.net\",\n            \"webbang.net\",\n            \"webevader.org\",\n            \"webfreer.com\",\n            \"webjb.org\",\n            \"weblagu.com\",\n            \"webmproject.org\",\n            \"webpack.de\",\n            \"webrtc.org\",\n            \"webrush.net\",\n            \"webs-tv.net\",\n            \"websitepulse.com\",\n            \"websnapr.com\",\n            \"webwarper.net\",\n            \"webworkerdaily.com\",\n            \"wechatlawsuit.com\",\n            \"weekmag.info\",\n            \"wefightcensorship.org\",\n            \"wefong.com\",\n            \"weiboleak.com\",\n            \"weihuo.org\",\n            \"weijingsheng.org\",\n            \"weiming.info\",\n            \"weiquanwang.org\",\n            \"weisuo.ws\",\n            \"welovecock.com\",\n            \"welt.de\",\n            \"wemigrate.org\",\n            \"wengewang.com\",\n            \"wengewang.org\",\n            \"wenhui.ch\",\n            \"wenweipo.com\",\n            \"wenxuecity.com\",\n            \"wenyunchao.com\",\n            \"wenzhao.ca\",\n            \"westca.com\",\n            \"westernshugdensociety.org\",\n            \"westernwolves.com\",\n            \"westkit.net\",\n            \"westpoint.edu\",\n            \"wetplace.com\",\n            \"wetpussygames.com\",\n            \"wexiaobo.org\",\n            \"wezhiyong.org\",\n            \"wezone.net\",\n            \"wforum.com\",\n            \"wha.la\",\n            \"whatblocked.com\",\n            \"whatbrowser.org\",\n            \"whatsapp.com\",\n            \"whatsapp.net\",\n            \"whatsonweibo.com\",\n            \"wheatseeds.org\",\n            \"wheelockslatin.com\",\n            \"whereiswerner.com\",\n            \"wheretowatch.com\",\n            \"whippedass.com\",\n            \"whispersystems.org\",\n            \"whodns.xyz\",\n            \"whoer.net\",\n            \"whotalking.com\",\n            \"whylover.com\",\n            \"whyx.org\",\n            \"widevine.com\",\n            \"wikaba.com\",\n            \"wikia.com\",\n            \"wikileaks-forum.com\",\n            \"wikileaks.ch\",\n            \"wikileaks.com\",\n            \"wikileaks.de\",\n            \"wikileaks.eu\",\n            \"wikileaks.lu\",\n            \"wikileaks.org\",\n            \"wikileaks.pl\",\n            \"wikilivres.info\",\n            \"wikimapia.org\",\n            \"wikimedia.org\",\n            \"wikinews.org\",\n            \"wikipedia.org\",\n            \"wikiquote.org\",\n            \"wikisource.org\",\n            \"wikiwand.com\",\n            \"wikiwiki.jp\",\n            \"wildammo.com\",\n            \"williamhill.com\",\n            \"willw.net\",\n            \"windowsphoneme.com\",\n            \"windscribe.com\",\n            \"windy.com\",\n            \"wingamestore.com\",\n            \"wingy.site\",\n            \"winning11.com\",\n            \"winwhispers.info\",\n            \"wionews.com\",\n            \"wire.com\",\n            \"wiredbytes.com\",\n            \"wiredpen.com\",\n            \"wireguard.com\",\n            \"wisdompubs.org\",\n            \"wisevid.com\",\n            \"wistia.com\",\n            \"withgoogle.com\",\n            \"withyoutube.com\",\n            \"witnessleeteaching.com\",\n            \"witopia.net\",\n            \"wizcrafts.net\",\n            \"wjbk.org\",\n            \"wn.com\",\n            \"wnacg.com\",\n            \"wnacg.org\",\n            \"wo.tc\",\n            \"woeser.com\",\n            \"woesermiddle-way.net\",\n            \"wokar.org\",\n            \"wolfax.com\",\n            \"wombo.ai\",\n            \"woolyss.com\",\n            \"woopie.jp\",\n            \"woopie.tv\",\n            \"wordpress.com\",\n            \"workatruna.com\",\n            \"workerdemo.org.hk\",\n            \"workerempowerment.org\",\n            \"workers.dev\",\n            \"workersthebig.net\",\n            \"workflow.is\",\n            \"worldcat.org\",\n            \"worldjournal.com\",\n            \"worldvpn.net\",\n            \"wow-life.net\",\n            \"wow.com\",\n            \"wowgirls.com\",\n            \"wowhead.com\",\n            \"wowlegacy.ml\",\n            \"wowporn.com\",\n            \"wowrk.com\",\n            \"woxinghuiguo.com\",\n            \"woyaolian.org\",\n            \"wozy.in\",\n            \"wp.com\",\n            \"wpoforum.com\",\n            \"wqyd.org\",\n            \"wrchina.org\",\n            \"wretch.cc\",\n            \"wsj.com\",\n            \"wsj.net\",\n            \"wsjhk.com\",\n            \"wtbn.org\",\n            \"wtfpeople.com\",\n            \"wuerkaixi.com\",\n            \"wufafangwen.com\",\n            \"wufi.org.tw\",\n            \"wuguoguang.com\",\n            \"wujie.net\",\n            \"wujieliulan.com\",\n            \"wukangrui.net\",\n            \"wuw.red\",\n            \"wuyanblog.com\",\n            \"wwe.com\",\n            \"wwitv.com\",\n            \"www1.biz\",\n            \"wwwhost.biz\",\n            \"wzyboy.im\",\n            \"x-art.com\",\n            \"x-berry.com\",\n            \"x-wall.org\",\n            \"x.co\",\n            \"x.company\",\n            \"x1949x.com\",\n            \"x24hr.com\",\n            \"x365x.com\",\n            \"xanga.com\",\n            \"xbabe.com\",\n            \"xbookcn.com\",\n            \"xbtce.com\",\n            \"xcafe.in\",\n            \"xcity.jp\",\n            \"xcritic.com\",\n            \"xda-developers.com\",\n            \"xerotica.com\",\n            \"xfiles.to\",\n            \"xfinity.com\",\n            \"xgmyd.com\",\n            \"xhamster.com\",\n            \"xianba.net\",\n            \"xianchawang.net\",\n            \"xianjian.tw\",\n            \"xianqiao.net\",\n            \"xiaobaiwu.com\",\n            \"xiaochuncnjp.com\",\n            \"xiaod.in\",\n            \"xiaohexie.com\",\n            \"xiaolan.me\",\n            \"xiaoma.org\",\n            \"xiaxiaoqiang.net\",\n            \"xiezhua.com\",\n            \"xihua.es\",\n            \"xinbao.de\",\n            \"xing.com\",\n            \"xinhuanet.org\",\n            \"xinjiangpolicefiles.org\",\n            \"xinmiao.com.hk\",\n            \"xinsheng.net\",\n            \"xinshijue.com\",\n            \"xinyubbs.net\",\n            \"xiongpian.com\",\n            \"xiuren.org\",\n            \"xixicui.icu\",\n            \"xizang-zhiye.org\",\n            \"xjp.cc\",\n            \"xjtravelguide.com\",\n            \"xkiwi.tk\",\n            \"xlfmtalk.com\",\n            \"xlfmwz.info\",\n            \"xm.com\",\n            \"xml-training-guide.com\",\n            \"xmovies.com\",\n            \"xn--4gq171p.com\",\n            \"xn--9pr62r24a.com\",\n            \"xn--czq75pvv1aj5c.org\",\n            \"xn--i2ru8q2qg.com\",\n            \"xn--ngstr-lra8j.com\",\n            \"xn--oiq.cc\",\n            \"xn--p8j9a0d9c9a.xn--q9jyb4c\",\n            \"xnxx.com\",\n            \"xpdo.net\",\n            \"xpud.org\",\n            \"xrentdvd.com\",\n            \"xsden.info\",\n            \"xskywalker.com\",\n            \"xskywalker.net\",\n            \"xtube.com\",\n            \"xuchao.net\",\n            \"xuchao.org\",\n            \"xuehua.us\",\n            \"xuite.net\",\n            \"xuzhiyong.net\",\n            \"xvbelink.com\",\n            \"xvideo.cc\",\n            \"xvideos-cdn.com\",\n            \"xvideos.com\",\n            \"xvideos.es\",\n            \"xvinlink.com\",\n            \"xxbbx.com\",\n            \"xxlmovies.com\",\n            \"xxuz.com\",\n            \"xxx.com\",\n            \"xxx.xxx\",\n            \"xxxfuckmom.com\",\n            \"xxxx.com.au\",\n            \"xxxy.biz\",\n            \"xxxy.info\",\n            \"xxxymovies.com\",\n            \"xys.org\",\n            \"xysblogs.org\",\n            \"xyy69.com\",\n            \"xyy69.info\",\n            \"y2mate.com\",\n            \"yadi.sk\",\n            \"yahoo.co.jp\",\n            \"yahoo.com\",\n            \"yahoo.com.hk\",\n            \"yahoo.com.tw\",\n            \"yahoo.net\",\n            \"yakbutterblues.com\",\n            \"yam.com\",\n            \"yam.org.tw\",\n            \"yande.re\",\n            \"yandex.com\",\n            \"yanghengjun.com\",\n            \"yangjianli.com\",\n            \"yasni.co.uk\",\n            \"yayabay.com\",\n            \"ycombinator.com\",\n            \"ydy.com\",\n            \"yeahteentube.com\",\n            \"yecl.net\",\n            \"yeelou.com\",\n            \"yeeyi.com\",\n            \"yegle.net\",\n            \"yes-news.com\",\n            \"yes.xxx\",\n            \"yes123.com.tw\",\n            \"yesasia.com\",\n            \"yesasia.com.hk\",\n            \"yespornplease.com\",\n            \"yeyeclub.com\",\n            \"ygto.com\",\n            \"yhcw.net\",\n            \"yibada.com\",\n            \"yibaochina.com\",\n            \"yidio.com\",\n            \"yigeni.com\",\n            \"yilubbs.com\",\n            \"yimg.com\",\n            \"yingsuoss.com\",\n            \"yinlei.org\",\n            \"yipub.com\",\n            \"yiyechat.com\",\n            \"yizhihongxing.com\",\n            \"yobit.net\",\n            \"yobt.com\",\n            \"yobt.tv\",\n            \"yogichen.org\",\n            \"yolasite.com\",\n            \"yomiuri.co.jp\",\n            \"yong.hu\",\n            \"yorkbbs.ca\",\n            \"you-get.org\",\n            \"youdontcare.com\",\n            \"youjizz.com\",\n            \"youmaker.com\",\n            \"youngpornvideos.com\",\n            \"youngspiration.hk\",\n            \"youpai.org\",\n            \"youporn.com\",\n            \"youporngay.com\",\n            \"your-freedom.net\",\n            \"yourepeat.com\",\n            \"yourlisten.com\",\n            \"yourlust.com\",\n            \"yourprivatevpn.com\",\n            \"yourtrap.com\",\n            \"yousendit.com\",\n            \"youshun12.com\",\n            \"youthforfreechina.org\",\n            \"youthnetradio.org\",\n            \"youthwant.com.tw\",\n            \"youtu.be\",\n            \"youtube-nocookie.com\",\n            \"youtube.com\",\n            \"youtubecn.com\",\n            \"youtubeeducation.com\",\n            \"youtubegaming.com\",\n            \"youtubekids.com\",\n            \"youversion.com\",\n            \"youwin.com\",\n            \"youxu.info\",\n            \"yt.be\",\n            \"ytht.net\",\n            \"ytimg.com\",\n            \"ytn.co.kr\",\n            \"yuanming.net\",\n            \"yuanzhengtang.org\",\n            \"yulghun.com\",\n            \"yunchao.net\",\n            \"yuntipub.com\",\n            \"yuvutu.com\",\n            \"yvesgeleyn.com\",\n            \"ywpw.com\",\n            \"yx51.net\",\n            \"yyii.org\",\n            \"yyjlymb.xyz\",\n            \"yzzk.com\",\n            \"z-lib.org\",\n            \"zacebook.com\",\n            \"zalmos.com\",\n            \"zannel.com\",\n            \"zaobao.com\",\n            \"zaobao.com.sg\",\n            \"zaozon.com\",\n            \"zapto.org\",\n            \"zattoo.com\",\n            \"zb.com\",\n            \"zdnet.com.tw\",\n            \"zello.com\",\n            \"zengjinyan.org\",\n            \"zenmate.com\",\n            \"zerohedge.com\",\n            \"zeronet.io\",\n            \"zeutch.com\",\n            \"zfreet.com\",\n            \"zgsddh.com\",\n            \"zgzcjj.net\",\n            \"zhanbin.net\",\n            \"zhangboli.net\",\n            \"zhangtianliang.com\",\n            \"zhanlve.org\",\n            \"zhenghui.org\",\n            \"zhengjian.org\",\n            \"zhengwunet.org\",\n            \"zhenlibu.info\",\n            \"zhenlibu1984.com\",\n            \"zhenxiang.biz\",\n            \"zhinengluyou.com\",\n            \"zhongguo.ca\",\n            \"zhongguorenquan.org\",\n            \"zhongguotese.net\",\n            \"zhongmeng.org\",\n            \"zhoushuguang.com\",\n            \"zhreader.com\",\n            \"zhuangbi.me\",\n            \"zhuanxing.cn\",\n            \"zhuatieba.com\",\n            \"zhuichaguoji.org\",\n            \"zi.media\",\n            \"zi5.me\",\n            \"ziddu.com\",\n            \"zillionk.com\",\n            \"zim.vn\",\n            \"zinio.com\",\n            \"ziporn.com\",\n            \"zippyshare.com\",\n            \"zkaip.com\",\n            \"zkiz.com\",\n            \"zmw.cn\",\n            \"zodgame.us\",\n            \"zoho.com\",\n            \"zomobo.net\",\n            \"zonaeuropa.com\",\n            \"zonghexinwen.com\",\n            \"zonghexinwen.net\",\n            \"zoogvpn.com\",\n            \"zootool.com\",\n            \"zoozle.net\",\n            \"zophar.net\",\n            \"zorrovpn.com\",\n            \"zozotown.com\",\n            \"zpn.im\",\n            \"zspeeder.me\",\n            \"zsrhao.com\",\n            \"zuo.la\",\n            \"zuobiao.me\",\n            \"zuola.com\",\n            \"zvereff.com\",\n            \"zynaima.com\",\n            \"zynamics.com\",\n            \"zyns.com\",\n            \"zyxel.com\",\n            \"zyzc9.com\",\n            \"zzcartoon.com\",\n            \"zzcloud.me\",\n            \"zzux.com\"\n        ]\n    ]\n];\n\nvar lastRule = '';\n\nfunction FindProxyForURL(url, host) {\n    for (var i = 0; i < rules.length; i++) {\n        ret = testHost(host, i);\n        if (ret != undefined)\n            return ret;\n    }\n    return 'DIRECT';\n}\n\nfunction testHost(host, index) {\n    for (var i = 0; i < rules[index].length; i++) {\n        for (var j = 0; j < rules[index][i].length; j++) {\n            lastRule = rules[index][i][j];\n            if (host == lastRule || host.endsWith('.' + lastRule))\n                return i % 2 == 0 ? 'DIRECT' : proxy;\n        }\n    }\n    lastRule = '';\n}\n\n// REF: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith\nif (!String.prototype.endsWith) {\n    String.prototype.endsWith = function(searchString, position) {\n        var subjectString = this.toString();\n        if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {\n            position = subjectString.length;\n        }\n        position -= searchString.length;\n        var lastIndex = subjectString.indexOf(searchString, position);\n        return lastIndex !== -1 && lastIndex === position;\n  };\n}\n"
  },
  {
    "path": "v2rayN/PacLib/Resources.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     此代码由工具生成。\n//     运行时版本:4.0.30319.42000\n//\n//     对此文件的更改可能会导致不正确的行为，并且如果\n//     重新生成代码，这些更改将会丢失。\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace PacLib {\n    using System;\n    \n    \n    /// <summary>\n    ///   一个强类型的资源类，用于查找本地化的字符串等。\n    /// </summary>\n    // 此类是由 StronglyTypedResourceBuilder\n    // 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。\n    // 若要添加或移除成员，请编辑 .ResX 文件，然后重新运行 ResGen\n    // (以 /str 作为命令选项)，或重新生成 VS 项目。\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"17.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    internal class Resources {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Resources() {\n        }\n        \n        /// <summary>\n        ///   返回此类使用的缓存的 ResourceManager 实例。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"PacLib.Resources\", typeof(Resources).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   重写当前线程的 CurrentUICulture 属性，对\n        ///   使用此强类型资源类的所有资源查找执行重写。\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        internal static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 var proxy = &apos;__PROXY__&apos;;\n        ///var rules = [\n        ///    [\n        ///        [],\n        ///        []\n        ///    ],\n        ///    [\n        ///        [\n        ///            &quot;aftygh.gov.tw&quot;,\n        ///            &quot;aide.gov.tw&quot;,\n        ///            &quot;aliyun.com&quot;,\n        ///            &quot;arte.gov.tw&quot;,\n        ///            &quot;baidu.com&quot;,\n        ///            &quot;chinaso.com&quot;,\n        ///            &quot;chinaz.com&quot;,\n        ///            &quot;chukuang.gov.tw&quot;,\n        ///            &quot;cycab.gov.tw&quot;,\n        ///            &quot;dbnsa.gov.tw&quot;,\n        ///            &quot;df.gov.tw&quot;,\n        ///            &quot;eastcoast-nsa.gov.tw&quot;,\n        ///            &quot;erv-nsa.gov.tw&quot;,\n        ///            &quot;grb.gov.tw&quot;,\n        ///            &quot;haosou.com&quot;,\n        ///     [字符串的其余部分被截断]&quot;; 的本地化字符串。\n        /// </summary>\n        internal static string pac {\n            get {\n                return ResourceManager.GetString(\"pac\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/PacLib/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  <assembly alias=\"System.Windows.Forms\" name=\"System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\" />\n  <data name=\"pac\" type=\"System.Resources.ResXFileRef, System.Windows.Forms\">\n    <value>Resources\\pac.txt;System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089;gb2312</value>\n  </data>\n</root>"
  },
  {
    "path": "v2rayN/ProtosLib/ProtosLib.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n  <PropertyGroup>\n    <TargetFramework>net6.0-windows</TargetFramework>\n    <Nullable>enable</Nullable>\t  \n  </PropertyGroup>\n\t\n\t<ItemGroup>\n\t\t<Protobuf Include=\"Statistics.proto\" />\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t\t<PackageReference Include=\"Google.Protobuf\" Version=\"3.22.3\" />\n\t\t<PackageReference Include=\"Grpc.Net.Client\" Version=\"2.52.0\" />\n\t\t<PackageReference Include=\"Grpc.Tools\" Version=\"2.54.0\">\n\t\t\t<PrivateAssets>all</PrivateAssets>\n\t\t\t<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>\n\t\t</PackageReference>\n\t</ItemGroup>\n\t\n</Project>\n"
  },
  {
    "path": "v2rayN/ProtosLib/Statistics.proto",
    "content": "﻿syntax = \"proto3\";\n\npackage v2ray.core.app.stats.command;\noption csharp_namespace = \"ProtosLib.Statistics\";\n\nmessage GetStatsRequest {\n  // Name of the stat counter.\n  string name = 1;\n  // Whether or not to reset the counter to fetching its value.\n  bool reset = 2;\n}\n\nmessage Stat {\n  string name = 1;\n  int64 value = 2;\n}\n\nmessage GetStatsResponse {\n  Stat stat = 1;\n}\n\nmessage QueryStatsRequest {\n  string pattern = 1;\n  bool reset = 2;\n}\n\nmessage QueryStatsResponse {\n  repeated Stat stat = 1;\n}\n\nmessage SysStatsRequest {\n}\n\nmessage SysStatsResponse {\n  uint32 NumGoroutine = 1;\n  uint32 NumGC = 2;\n  uint64 Alloc = 3;\n  uint64 TotalAlloc = 4;\n  uint64 Sys = 5;\n  uint64 Mallocs = 6;\n  uint64 Frees = 7;\n  uint64 LiveObjects = 8;\n  uint64 PauseTotalNs = 9;\n  uint32 Uptime = 10;\n}\n\nservice StatsService {\n  rpc GetStats(GetStatsRequest) returns (GetStatsResponse) {}\n  rpc QueryStats(QueryStatsRequest) returns (QueryStatsResponse) {}\n  rpc GetSysStats(SysStatsRequest) returns (SysStatsResponse) {}\n}\n\nmessage Config {}\n"
  },
  {
    "path": "v2rayN/ProtosLib/Tests.cs",
    "content": "﻿using ProtosLib.Statistics;\n\nnamespace ProtosLib\n{\n    public class Tests\n    {\n        private StatsService.StatsServiceClient client_;\n\n        public Tests()\n        {\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/App.xaml",
    "content": "﻿<Application\n    x:Class=\"v2rayN.App\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:avalonEdit=\"http://icsharpcode.net/sharpdevelop/avalonedit\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    ShutdownMode=\"OnExplicitShutdown\"\n    StartupUri=\"Views/MainWindow.xaml\">\n    <Application.Resources>\n        <ResourceDictionary xmlns:system=\"clr-namespace:System;assembly=mscorlib\">\n            <ResourceDictionary.MergedDictionaries>\n                <materialDesign:BundledTheme BaseTheme=\"Inherit\"\n                                     ColorAdjustment=\"{materialDesign:ColorAdjustment}\"\n                                     PrimaryColor=\"Blue\"\n                    SecondaryColor=\"Blue\" />\n\n                <ResourceDictionary Source=\"pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml\" />\n\n            </ResourceDictionary.MergedDictionaries>\n            <system:Double x:Key=\"MenuItemHeight\">26</system:Double>\n            <system:Double x:Key=\"StdFontSize\">12</system:Double>\n            <system:Double x:Key=\"StdFontSize1\">13</system:Double>\n            <system:Double x:Key=\"StdFontSize2\">14</system:Double>\n            <system:Double x:Key=\"StdFontSizeMsg\">11</system:Double>\n            <Thickness\n                x:Key=\"ServerItemMargin\"\n                Bottom=\"4\"\n                Left=\"4\"\n                Right=\"4\"\n                Top=\"4\" />\n            <Thickness\n                x:Key=\"SettingItemMargin\"\n                Bottom=\"8\"\n                Left=\"8\"\n                Right=\"8\"\n                Top=\"8\" />\n            <Style\n                x:Key=\"ModuleTitle\"\n                BasedOn=\"{StaticResource MaterialDesignTextBlock}\"\n                TargetType=\"{x:Type TextBlock}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize2}\" />\n            </Style>\n            <Style\n                x:Key=\"ToolbarTextBlock\"\n                BasedOn=\"{StaticResource MaterialDesignTextBlock}\"\n                TargetType=\"{x:Type TextBlock}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n            </Style>\n            <Style\n                x:Key=\"StatusbarItem\"\n                BasedOn=\"{StaticResource MaterialDesignTextBlock}\"\n                TargetType=\"{x:Type TextBlock}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n                <Setter Property=\"Padding\" Value=\"0\" />\n            </Style>\n            <Style TargetType=\"{x:Type TextElement}\">\n                <Setter Property=\"FontWeight\" Value=\"Regular\" />\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource MaterialDesignBody}\" />\n            </Style>\n            <Style TargetType=\"{x:Type TextBlock}\">\n                <Setter Property=\"FontWeight\" Value=\"Regular\" />\n                <Setter Property=\"Foreground\" Value=\"{DynamicResource MaterialDesignBody}\" />\n            </Style>\n            <Style x:Key=\"lvItemSelected\" TargetType=\"{x:Type ListViewItem}\">\n                <Setter Property=\"Height\" Value=\"20\" />\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n                <Style.Triggers>\n                    <Trigger Property=\"IsSelected\" Value=\"true\">\n                        <Setter Property=\"Background\" Value=\"{DynamicResource PrimaryHueLightBrush}\" />\n                    </Trigger>\n                    <Trigger Property=\"IsMouseOver\" Value=\"true\">\n                        <Setter Property=\"Background\" Value=\"{DynamicResource PrimaryHueMidBrush}\" />\n                    </Trigger>\n                </Style.Triggers>\n            </Style>\n\n            <Style x:Key=\"GridViewColumnHeaderStyle\" TargetType=\"{x:Type GridViewColumnHeader}\">\n                <Setter Property=\"Height\" Value=\"30\" />\n            </Style>\n            <Style\n                x:Key=\"ListItemCheckBox\"\n                BasedOn=\"{StaticResource MaterialDesignUserForegroundCheckBox}\"\n                TargetType=\"{x:Type CheckBox}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n            </Style>\n            <Style\n                x:Key=\"DefButton\"\n                BasedOn=\"{StaticResource MaterialDesignRaisedButton}\"\n                TargetType=\"{x:Type ButtonBase}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize1}\" />\n            </Style>\n            <Style\n                x:Key=\"DefContextMenu\"\n                BasedOn=\"{StaticResource MaterialDesignContextMenu}\"\n                TargetType=\"{x:Type ContextMenu}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize1}\" />\n                <Setter Property=\"FontFamily\" Value=\"{x:Static conv:MaterialDesignFonts.MyFont}\" />\n            </Style>\n\n            <Style\n                x:Key=\"ToolbarMenu\"\n                BasedOn=\"{StaticResource MaterialDesignMenu}\"\n                TargetType=\"{x:Type Menu}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize1}\" />\n                <Setter Property=\"FontFamily\" Value=\"{x:Static conv:MaterialDesignFonts.MyFont}\" />\n            </Style>\n\n            <Style\n                x:Key=\"DefComboBox\"\n                BasedOn=\"{StaticResource MaterialDesignComboBox}\"\n                TargetType=\"{x:Type ComboBox}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n                <Setter Property=\"HorizontalAlignment\" Value=\"Left\" />\n            </Style>\n            <Style\n                x:Key=\"DefDataGrid\"\n                BasedOn=\"{StaticResource MaterialDesignDataGrid}\"\n                TargetType=\"{x:Type DataGrid}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n            </Style>\n            <Style\n                x:Key=\"DefTextBox\"\n                BasedOn=\"{StaticResource MaterialDesignTextBox}\"\n                TargetType=\"{x:Type TextBox}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n            </Style>\n            <Style\n                x:Key=\"MyOutlinedTextBox\"\n                BasedOn=\"{StaticResource MaterialDesignOutlinedTextBox}\"\n                TargetType=\"{x:Type TextBox}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n            </Style>\n            <Style\n                x:Key=\"MyGroupBox\"\n                BasedOn=\"{StaticResource MaterialDesignGroupBox}\"\n                TargetType=\"{x:Type GroupBox}\">\n                <Setter Property=\"FontSize\" Value=\"{DynamicResource StdFontSize}\" />\n            </Style>\n            <Style\n                x:Key=\"MyChipListBoxItem\"\n                BasedOn=\"{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBoxItem}\"\n                TargetType=\"{x:Type ListBoxItem}\">\n                <Setter Property=\"Margin\" Value=\"-2,0\" />\n            </Style>\n            \n            \n            \n        </ResourceDictionary>\n    </Application.Resources>\n</Application>"
  },
  {
    "path": "v2rayN/v2rayN/App.xaml.cs",
    "content": "﻿using System.Windows;\nusing System.Windows.Threading;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Tool;\nusing v2rayN.ViewModels;\nusing v2rayN.Tool;\nusing System.Net;\nusing HiddifyN.Tool;\nusing v2rayN.Views;\nusing System.IO.Pipes;\nusing System.IO;\n\nnamespace v2rayN\n{\n    /// <summary>\n    /// Interaction logic for App.xaml\n    /// </summary>\n    public partial class App : Application\n    {\n        public static EventWaitHandle ProgramStarted;\n        public static bool IsNewInstance = false;\n        private static Config _config;\n        \n\n        public App()\n        {\n            // Locator.CurrentMutable.RegisterViewsForViewModels(Assembly.GetCallingAssembly());\n            this.DispatcherUnhandledException += App_DispatcherUnhandledException;\n            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;\n            TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;\n        }\n\n        /// <summary>\n        /// 只打开一个进程\n        /// </summary>\n        /// <param name=\"e\"></param>\n        protected override void OnStartup(StartupEventArgs e)\n        {\n\n            DeepLinking.RegisterSchemes();\n            \n            Global.ExePathKey = Utils.GetMD5(Utils.GetExePath());\n\n            var rebootas = (e.Args ?? new string[] { }).Any(t => t == Global.RebootAs);\n            ProgramStarted = new EventWaitHandle(false, EventResetMode.AutoReset, Global.ExePathKey, out bool bCreatedNew);\n            if (!rebootas && !bCreatedNew)\n            {\n                ProgramStarted.Set();\n                IsNewInstance = true;\n                sendLinkToUi();\n            }\n\n            \n            Global.processJob = new Job();\n\n            Logging.Setup();\n            Init();\n            Logging.LoggingEnabled(_config.guiItem.enableLog);\n            Utils.SaveLog($\"v2rayN start up | {Utils.GetVersion()} | {Utils.GetExePath()}\");\n            Logging.ClearLogs();\n\n            Thread.CurrentThread.CurrentUICulture = new(_config.uiItem.currentLanguage);\n            \n            base.OnStartup(e);\n            \n        }\n\n        private void sendLinkToUi()\n        {\n            try\n            {\n                using (var pipeClient = new NamedPipeClientStream(\"HiddifyPipe\"))\n                {\n                    pipeClient.Connect();\n\n                    using (var writer = new StreamWriter(pipeClient))\n                    {\n                        var args = Environment.GetCommandLineArgs();\n                        // Write the message to the named pipe\n                        string message = args.Length>1? args[1]:\"\";\n                        writer.WriteLine(message);\n                        writer.Flush();\n                        Thread.Sleep(10000);\n                    }\n                    \n                    pipeClient.Close();\n                }\n            }\n            catch (Exception ex)\n            {\n                // Handle any exceptions that occur while sending the message\n                // ...\n            }\n            \n\n            // Exit the new instance of the application\n            Application.Current.Shutdown();\n        }\n        private void Init()\n        {\n            if (ConfigHandler.LoadConfig(ref _config) != 0)\n            {\n                UI.ShowWarning($\"Loading GUI configuration file is abnormal,please restart the application{Environment.NewLine}加载GUI配置文件异常,请重启应用\");\n                Current.Shutdown();\n                Environment.Exit(0);\n                return;\n            }\n            //if (RuntimeInformation.ProcessArchitecture != Architecture.X86 && RuntimeInformation.ProcessArchitecture != Architecture.X64)\n            //{\n            //    _config.guiItem.enableStatistics = false;\n            //}\n        }\n\n        private void App_DispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)\n        {\n            Utils.SaveLog(\"App_DispatcherUnhandledException\", e.Exception);\n            e.Handled = true;\n        }\n\n        private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)\n        {\n            if (e.ExceptionObject != null)\n            {\n                Utils.SaveLog(\"CurrentDomain_UnhandledException\", (Exception)e.ExceptionObject!);\n            }\n        }\n\n        private void TaskScheduler_UnobservedTaskException(object? sender, UnobservedTaskExceptionEventArgs e)\n        {\n            Utils.SaveLog(\"TaskScheduler_UnobservedTaskException\", e.Exception);\n        }\n\n\n\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/AssemblyInfo.cs",
    "content": "using System.Windows;\n\n[assembly: ThemeInfo(\n    ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located\n                                     //(used if a resource is not found in the page,\n                                     // or application resource dictionaries)\n    ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located\n                                              //(used if a resource is not found in the page,\n                                              // app, or any theme specific resource dictionaries)\n)]"
  },
  {
    "path": "v2rayN/v2rayN/Base/DownloaderHelper.cs",
    "content": "﻿using Downloader;\nusing System.IO;\nusing System.Net;\n\nnamespace v2rayN.Base\n{\n    internal class DownloaderHelper\n    {\n        private static readonly Lazy<DownloaderHelper> _instance = new(() => new());\n        public static DownloaderHelper Instance => _instance.Value;\n\n        public async Task<string?> DownloadStringAsync(IWebProxy? webProxy, string url, string? userAgent, int timeout)\n        {\n            if (string.IsNullOrEmpty(url))\n            {\n                return null;\n            }\n\n            Uri uri = new(url);\n            //Authorization Header\n            var headers = new WebHeaderCollection();\n            if (!Utils.IsNullOrEmpty(uri.UserInfo))\n            {\n                headers.Add(HttpRequestHeader.Authorization, \"Basic \" + Utils.Base64Encode(uri.UserInfo));\n            }\n\n            var downloadOpt = new DownloadConfiguration()\n            {\n                Timeout = timeout * 1000,\n                MaxTryAgainOnFailover = 2,\n                RequestConfiguration =\n                {\n                    Headers = headers,\n                    UserAgent = userAgent,\n                    Timeout = timeout * 1000,\n                    Proxy = webProxy\n                }\n            };\n\n            using var downloader = new DownloadService(downloadOpt);\n            downloader.DownloadFileCompleted += (sender, value) =>\n            {\n                if (value.Error != null)\n                    throw value.Error;\n                \n            };\n\n            using var cts = new CancellationTokenSource();\n            using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);\n            using StreamReader reader = new(stream);\n\n            downloadOpt = null;\n\n            return reader.ReadToEnd();\n        }\n\n        public async Task DownloadDataAsync4Speed(IWebProxy webProxy, string url, IProgress<string> progress, int timeout)\n        {\n            if (string.IsNullOrEmpty(url))\n            {\n                throw new ArgumentNullException(nameof(url));\n            }\n\n            var downloadOpt = new DownloadConfiguration()\n            {\n                Timeout = timeout * 1000,\n                MaxTryAgainOnFailover = 2,\n                RequestConfiguration =\n                {\n                    Timeout= timeout * 1000,\n                    Proxy = webProxy\n                }\n            };\n\n            DateTime totalDatetime = DateTime.Now;\n            int totalSecond = 0;\n            var hasValue = false;\n            double maxSpeed = 0;\n            using var downloader = new DownloadService(downloadOpt);\n            //downloader.DownloadStarted += (sender, value) =>\n            //{\n            //    if (progress != null)\n            //    {\n            //        progress.Report(\"Start download data...\");\n            //    }\n            //};\n            downloader.DownloadProgressChanged += (sender, value) =>\n            {\n                TimeSpan ts = (DateTime.Now - totalDatetime);\n                if (progress != null && ts.Seconds > totalSecond)\n                {\n                    hasValue = true;\n                    totalSecond = ts.Seconds;\n                    if (value.BytesPerSecondSpeed > maxSpeed)\n                    {\n                        maxSpeed = value.BytesPerSecondSpeed;\n                        var speed = (maxSpeed / 1000 / 1000).ToString(\"#0.0\");\n                        progress.Report(speed);\n                    }\n                }\n            };\n            downloader.DownloadFileCompleted += (sender, value) =>\n            {\n                if (progress != null)\n                {\n                    if (!hasValue && value.Error != null)\n                    {\n                        progress.Report(value.Error?.Message);\n                    }\n                }\n            };\n            //progress.Report(\"......\");\n            using var cts = new CancellationTokenSource();\n            cts.CancelAfter(timeout * 1000);\n            using var stream = await downloader.DownloadFileTaskAsync(address: url, cts.Token);\n\n            downloadOpt = null;\n        }\n\n        public async Task DownloadFileAsync(IWebProxy? webProxy, string url, string fileName, IProgress<double> progress, int timeout)\n        {\n            if (string.IsNullOrEmpty(url))\n            {\n                throw new ArgumentNullException(nameof(url));\n            }\n            if (string.IsNullOrEmpty(fileName))\n            {\n                throw new ArgumentNullException(nameof(fileName));\n            }\n            if (File.Exists(fileName))\n            {\n                File.Delete(fileName);\n            }\n\n            var downloadOpt = new DownloadConfiguration()\n            {\n                Timeout = timeout * 1000,\n                MaxTryAgainOnFailover = 2,\n                RequestConfiguration =\n                {\n                    Timeout= timeout * 1000,\n                    Proxy = webProxy\n                }\n            };\n\n            var progressPercentage = 0;\n            var hasValue = false;\n            using var downloader = new DownloadService(downloadOpt);\n            downloader.DownloadStarted += (sender, value) =>\n            {\n                progress?.Report(0);\n            };\n            downloader.DownloadProgressChanged += (sender, value) =>\n            {\n                hasValue = true;\n                var percent = (int)value.ProgressPercentage;//   Convert.ToInt32((totalRead * 1d) / (total * 1d) * 100);\n                if (progressPercentage != percent && percent % 10 == 0)\n                {\n                    progressPercentage = percent;\n                    progress.Report(percent);\n                }\n            };\n            downloader.DownloadFileCompleted += (sender, value) =>\n            {\n                if (progress != null)\n                {\n                    if (hasValue && value.Error == null)\n                    {\n                        progress.Report(101);\n                    }\n                }\n            };\n\n            using var cts = new CancellationTokenSource();\n            await downloader.DownloadFileTaskAsync(url, fileName, cts.Token).WaitAsync(TimeSpan.FromSeconds(timeout), cts.Token);\n\n            downloadOpt = null;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Base/HttpClientHelper.cs",
    "content": "﻿using System.IO;\nusing System.Net.Http;\nusing System.Net.Mime;\nusing System.Text;\n\nnamespace v2rayN.Base\n{\n    /// <summary>\n    /// </summary>\n    public class HttpClientHelper\n    {\n        private static readonly Lazy<HttpClientHelper> _instance = new(() =>\n        {\n            HttpClientHandler handler = new() { UseCookies = false };\n            HttpClientHelper helper = new(new HttpClient(handler));\n            return helper;\n        });\n\n        public static HttpClientHelper Instance => _instance.Value;\n        private readonly HttpClient httpClient;\n\n        private HttpClientHelper(HttpClient httpClient) => this.httpClient = httpClient;\n\n        public async Task<string?> GetAsync(string url)\n        {\n            if (string.IsNullOrEmpty(url)) return null;\n            return await httpClient.GetStringAsync(url);\n        }\n\n        public async Task<string?> GetAsync(HttpClient client, string url, CancellationToken token = default)\n        {\n            if (string.IsNullOrWhiteSpace(url)) return null;\n            return await client.GetStringAsync(url, token);\n        }\n\n        public async Task PutAsync(string url, Dictionary<string, string> headers)\n        {\n            var jsonContent = Utils.ToJson(headers);\n            var content = new StringContent(jsonContent, Encoding.UTF8, MediaTypeNames.Application.Json);\n\n            var result = await httpClient.PutAsync(url, content);\n        }\n\n        public static async Task DownloadFileAsync(HttpClient client, string url, string fileName, IProgress<double>? progress, CancellationToken token = default)\n        {\n            ArgumentNullException.ThrowIfNull(url);\n            ArgumentNullException.ThrowIfNull(fileName);\n            if (File.Exists(fileName)) File.Delete(fileName);\n\n            using var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);\n\n            if (!response.IsSuccessStatusCode) throw new Exception(response.StatusCode.ToString());\n\n            var total = response.Content.Headers.ContentLength ?? -1L;\n            var canReportProgress = total != -1 && progress != null;\n\n            using var stream = await response.Content.ReadAsStreamAsync(token);\n            using var file = File.Create(fileName);\n            var totalRead = 0L;\n            var buffer = new byte[1024 * 1024];\n            var progressPercentage = 0;\n\n            while (true)\n            {\n                token.ThrowIfCancellationRequested();\n\n                var read = await stream.ReadAsync(buffer, token);\n                totalRead += read;\n\n                if (read == 0) break;\n                file.Write(buffer, 0, read);\n\n                if (canReportProgress)\n                {\n                    var percent = (int)(100.0 * totalRead / total);\n                    //if (progressPercentage != percent && percent % 10 == 0)\n                    {\n                        progressPercentage = percent;\n                        progress!.Report(percent);\n                    }\n                }\n            }\n            if (canReportProgress)\n            {\n                progress!.Report(101);\n            }\n        }\n\n        public async Task DownloadDataAsync4Speed(HttpClient client, string url, IProgress<string> progress, CancellationToken token = default)\n        {\n            if (string.IsNullOrEmpty(url))\n            {\n                throw new ArgumentNullException(nameof(url));\n            }\n\n            var response = await client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead, token);\n\n            if (!response.IsSuccessStatusCode)\n            {\n                throw new Exception(response.StatusCode.ToString());\n            }\n\n            //var total = response.Content.Headers.ContentLength.HasValue ? response.Content.Headers.ContentLength.Value : -1L;\n            //var canReportProgress = total != -1 && progress != null;\n\n            using var stream = await response.Content.ReadAsStreamAsync(token);\n            var totalRead = 0L;\n            var buffer = new byte[1024 * 64];\n            var isMoreToRead = true;\n            string progressSpeed = string.Empty;\n            DateTime totalDatetime = DateTime.Now;\n            int totalSecond = 0;\n\n            do\n            {\n                if (token.IsCancellationRequested)\n                {\n                    if (totalRead > 0)\n                    {\n                        return;\n                    }\n                    else\n                    {\n                        token.ThrowIfCancellationRequested();\n                    }\n                }\n\n                var read = await stream.ReadAsync(buffer, token);\n\n                if (read == 0)\n                {\n                    isMoreToRead = false;\n                }\n                else\n                {\n                    var data = new byte[read];\n                    buffer.ToList().CopyTo(0, data, 0, read);\n\n                    totalRead += read;\n\n                    TimeSpan ts = (DateTime.Now - totalDatetime);\n                    if (progress != null && ts.Seconds > totalSecond)\n                    {\n                        totalSecond = ts.Seconds;\n                        var speed = (totalRead * 1d / ts.TotalMilliseconds / 1000).ToString(\"#0.0\");\n                        if (progressSpeed != speed)\n                        {\n                            progressSpeed = speed;\n                            progress.Report(speed);\n                        }\n                    }\n                }\n            } while (isMoreToRead);\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Base/MyDGTextColumn.cs",
    "content": "﻿using System.Windows.Controls;\n\nnamespace v2rayN.Base\n{\n    internal class MyDGTextColumn : DataGridTextColumn\n    {\n        public string ExName { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Base/SqliteHelper.cs",
    "content": "﻿using SQLite;\nusing System.Collections;\n\nnamespace v2rayN.Base\n{\n    public sealed class SqliteHelper\n    {\n        private static readonly Lazy<SqliteHelper> _instance = new(() => new());\n        public static SqliteHelper Instance => _instance.Value;\n        private string _connstr;\n        private SQLiteConnection _db;\n        private SQLiteAsyncConnection _dbAsync;\n        private static readonly object objLock = new();\n\n        public SqliteHelper()\n        {\n            _connstr = Utils.GetConfigPath(Global.ConfigDB);\n            _db = new SQLiteConnection(_connstr, false);\n            _dbAsync = new SQLiteAsyncConnection(_connstr, false);\n        }\n\n        public CreateTableResult CreateTable<T>()\n        {\n            return _db.CreateTable<T>();\n        }\n\n        public int Insert(object model)\n        {\n            return _db.Insert(model);\n        }\n\n        public int InsertAll(IEnumerable models)\n        {\n            lock (objLock)\n            {\n                return _db.InsertAll(models);\n            }\n        }\n\n        public async Task<int> InsertAsync(object model)\n        {\n            return await _dbAsync.InsertAsync(model);\n        }\n\n        public int Replace(object model)\n        {\n            lock (objLock)\n            {\n                return _db.InsertOrReplace(model);\n            }\n        }\n\n        public async Task<int> Replacesync(object model)\n        {\n            return await _dbAsync.InsertOrReplaceAsync(model);\n        }\n\n        public int Update(object model)\n        {\n            lock (objLock)\n            {\n                return _db.Update(model);\n            }\n        }\n\n        public async Task<int> UpdateAsync(object model)\n        {\n            return await _dbAsync.UpdateAsync(model);\n        }\n\n        public int UpdateAll(IEnumerable models)\n        {\n            lock (objLock)\n            {\n                return _db.UpdateAll(models);\n            }\n        }\n\n        public int Delete(object model)\n        {\n            lock (objLock)\n            {\n                return _db.Delete(model);\n            }\n        }\n\n        public async Task<int> DeleteAsync(object model)\n        {\n            return await _dbAsync.DeleteAsync(model);\n        }\n\n        public List<T> Query<T>(string sql) where T : new()\n        {\n            return _db.Query<T>(sql);\n        }\n\n        public async Task<List<T>> QueryAsync<T>(string sql) where T : new()\n        {\n            return await _dbAsync.QueryAsync<T>(sql);\n        }\n\n        public int Execute(string sql)\n        {\n            return _db.Execute(sql);\n        }\n\n        public async Task<int> ExecuteAsync(string sql)\n        {\n            return await _dbAsync.ExecuteAsync(sql);\n        }\n\n        public TableQuery<T> Table<T>() where T : new()\n        {\n            return _db.Table<T>();\n        }\n\n        public AsyncTableQuery<T> TableAsync<T>() where T : new()\n        {\n            return _dbAsync.Table<T>();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Base/StringEx.cs",
    "content": "﻿using System.Diagnostics.CodeAnalysis;\nusing System.IO;\n\nnamespace v2rayN.Base\n{\n    internal static class StringEx\n    {\n        public static bool IsNullOrEmpty([NotNullWhen(false)] this string? value)\n        {\n            return string.IsNullOrEmpty(value);\n        }\n\n        public static bool IsNullOrWhiteSpace([NotNullWhen(false)] this string? value)\n        {\n            return string.IsNullOrWhiteSpace(value);\n        }\n\n        public static bool BeginWithAny(this string s, IEnumerable<char> chars)\n        {\n            if (s.IsNullOrEmpty()) return false;\n            return chars.Contains(s[0]);\n        }\n\n        public static bool IsWhiteSpace(this string value)\n        {\n            foreach (char c in value)\n            {\n                if (char.IsWhiteSpace(c)) continue;\n\n                return false;\n            }\n            return true;\n        }\n\n        public static IEnumerable<string> NonWhiteSpaceLines(this TextReader reader)\n        {\n            string? line;\n            while ((line = reader.ReadLine()) != null)\n            {\n                if (line.IsWhiteSpace()) continue;\n                yield return line;\n            }\n        }\n\n        public static string TrimEx(this string? value)\n        {\n            return value == null ? string.Empty : value.Trim();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Converters/DelayColorConverter.cs",
    "content": "﻿using System.Windows.Data;\nusing System.Windows.Media;\n\nnamespace v2rayN.Converters\n{\n    public class DelayColorConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n        {\n            int.TryParse(value.ToString(), out var delay);\n\n            if (delay <= 0)\n                return new SolidColorBrush(Colors.Red);\n            if (delay <= 200)\n                return new SolidColorBrush(Colors.Green);\n            else\n                return new SolidColorBrush(Colors.IndianRed);\n        }\n\n        public object? ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)\n        {\n            return null;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Converters/LocalizeConverter.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Globalization;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Data;\nusing System.Windows;\nusing v2rayN.Mode;\n\nnamespace v2rayN.Converters\n{\n    public class LocalizeConverter : IValueConverter\n    {\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            if (value is ProxyModeEnum)\n                return ((ProxyModeEnum)value).ToLocalizedDescriptionString();\n            string resourceName = value.ToString();\n            return Application.Current.FindResource(resourceName);\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Converters/MaterialDesignFonts.cs",
    "content": "﻿using System.Windows.Media;\nusing v2rayN.Handler;\n\nnamespace v2rayN.Converters\n{\n    public class MaterialDesignFonts\n    {\n        public static FontFamily MyFont { get; }\n\n        static MaterialDesignFonts()\n        {\n            try\n            {\n                var fontFamily = LazyConfig.Instance.GetConfig().uiItem.currentFontFamily;\n                if (!string.IsNullOrEmpty(fontFamily))\n                {\n                    var fontPath = Utils.GetFontsPath();\n                    MyFont = new FontFamily(new Uri(@$\"file:///{fontPath}\\\"), $\"./#{fontFamily}\");\n                }\n            }\n            catch\n            {\n            }\n            MyFont ??= new FontFamily(\"Microsoft YaHei\");\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Converters/SizeConverter.cs",
    "content": "﻿using System.Globalization;\nusing System.Windows.Data;\nusing System.Windows.Media;\n\nnamespace v2rayN.Converters\n{\n    public class SizeConverter : IValueConverter\n    {\n        private static readonly string[] SizeSuffixes = { \"B\", \"KB\", \"MB\", \"GB\", \"TB\", \"PB\", \"EB\", \"ZB\", \"YB\" };\n\n\n        private static bool IsNumber(object value)\n        {\n            return value is sbyte || value is byte ||\n                   value is short || value is ushort ||\n                   value is int || value is uint ||\n                   value is long || value is ulong ||\n                   value is float || value is double ||\n                   value is decimal;\n        }\n\n        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            if (value == null || !IsNumber(value))\n            {\n                return null;\n            }\n\n            long fileSizeInBytes = System.Convert.ToInt64(value);\n            if (fileSizeInBytes == 0)\n            {\n                return \"0 B\";\n            }\n\n            var sizeIndex = (int)Math.Floor(Math.Log(fileSizeInBytes, 1024));\n            var size = fileSizeInBytes / Math.Pow(1024, sizeIndex);\n            var sizeSuffix = SizeSuffixes[sizeIndex];\n            var formattedSize = string.Format(\"{0:n1}\", size);\n\n            return $\"{formattedSize} {sizeSuffix}\";\n        }\n\n        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)\n        {\n            throw new NotImplementedException();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/FodyWeavers.xml",
    "content": "﻿<Weavers xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"FodyWeavers.xsd\">\n  <ReactiveUI />\n</Weavers>"
  },
  {
    "path": "v2rayN/v2rayN/Global.cs",
    "content": "﻿using System.IO;\n\nnamespace v2rayN\n{\n    internal class Global\n    {\n        #region const\n\n        public const string githubUrl = \"https://github.com\";\n        public const string githubApiUrl = \"https://api.github.com/repos\";\n        public const string v2rayWebsiteUrl = @\"https://www.hiddify.com/\";\n        public const string AboutUrl = @\"https://github.com/hiddify/HiddifyDesktopN\";\n        public const string UpdateUrl = AboutUrl + @\"/releases\";\n        public const string v2flyCoreUrl = \"https://github.com/v2fly/v2ray-core/releases\";\n        public const string xrayCoreUrl = \"https://github.com/hiddify/hiddify-Xray-core/releases\";\n        public const string SagerNetCoreUrl = \"https://github.com/SagerNet/v2ray-core/releases\";\n        public const string NUrl = @\"https://github.com/hiddify/HiddifyDesktopN/releases\";\n        public const string clashCoreUrl = \"https://github.com/Dreamacro/clash/releases\";\n        public const string clashMetaCoreUrl = \"https://github.com/MetaCubeX/Clash.Meta/releases\";\n        public const string hysteriaCoreUrl = \"https://github.com/apernet/hysteria/releases\";\n        public const string naiveproxyCoreUrl = \"https://github.com/klzgrad/naiveproxy/releases\";\n        public const string tuicCoreUrl = \"https://github.com/EAimTY/tuic/releases\";\n        public const string singboxCoreUrl = \"https://github.com/SagerNet/sing-box/releases\";\n        public const string geoUrl = \"https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/{0}.dat\";\n        public const string CustomRoutingListUrl = @\"https://raw.githubusercontent.com/2dust/v2rayCustomRoutingList/master/\";\n        public const string singboxGeoUrl = \"https://github.com/soffchen/sing-{0}/releases/latest/download/{0}.db\";\n        public const string SpeedPingTestUrl = @\"https://www.google.com/generate_204\";\n        public const string SpeedPingTestUrlGoogle = @\"https://www.google.com/generate_204\";\n        public const string SpeedPingTestUrlCloadFlare = @\"https://cp.cloudflare.com/generate_2\";\n        public const int DefaultUpdateSubUsageIntervalSeconds = 60;\n        \n\n        public const string PromotionUrl = @\"dGc6Ly9yZXNvbHZlP2RvbWFpbj1oaWRkaWZ5\";\n        public const string ConfigFileName = \"guiNConfig.json\";\n        public const string ConfigDB = \"guiNDB.db\";\n        public const string coreConfigFileName = \"config.json\";\n        public const string corePreConfigFileName = \"configPre.json\";\n\n        public const string v2raySampleClient = \"v2rayN.Sample.SampleClientConfig\";\n        public const string SingboxSampleClient = \"v2rayN.Sample.SingboxSampleClientConfig\";\n        public const string v2raySampleHttprequestFileName = \"v2rayN.Sample.SampleHttprequest\";\n        public const string v2raySampleHttpresponseFileName = \"v2rayN.Sample.SampleHttpresponse\";\n        public const string v2raySampleInbound = \"v2rayN.Sample.SampleInbound\";\n        public const string CustomRoutingFileName = \"v2rayN.Sample.custom_routing_\";\n\n        public const string TunSingboxFileName = \"v2rayN.Sample.tun_singbox\";\n        public const string TunSingboxDNSFileName = \"v2rayN.Sample.tun_singbox_dns\";\n        public const string TunSingboxInboundFileName = \"v2rayN.Sample.tun_singbox_inbound\";\n        public const string TunSingboxRulesFileName = \"v2rayN.Sample.tun_singbox_rules\";\n\n        public const string DNSV2rayNormalFileName = \"v2rayN.Sample.dns_v2ray_normal\";\n        public const string DNSSingboxNormalFileName = \"v2rayN.Sample.dns_singbox_normal\";\n\n        public const string DefaultSecurity = \"auto\";\n        public const string DefaultNetwork = \"tcp\";\n        public const string TcpHeaderHttp = \"http\";\n        public const string None = \"none\";\n        public const string agentTag = \"proxy\";\n        public const string directTag = \"direct\";\n        public const string blockTag = \"block\";\n        public const string StreamSecurity = \"tls\";\n        public const string StreamSecurityReality = \"reality\";\n        public const string InboundSocks = \"socks\";\n        public const string InboundHttp = \"http\";\n        public const string InboundSocks2 = \"socks2\";\n        public const string InboundHttp2 = \"http2\";\n        public const string Loopback = \"127.0.0.1\";\n        public const string InboundAPITagName = \"api\";\n        public const string InboundAPIProtocal = \"dokodemo-door\";\n\n        public const string vmessProtocol = \"vmess://\";\n        public const string vmessProtocolLite = \"vmess\";\n        public const string ssProtocol = \"ss://\";\n        public const string ssProtocolLite = \"shadowsocks\";\n        public const string socksProtocol = \"socks://\";\n        public const string socksProtocolLite = \"socks\";\n        public const string httpProtocol = \"http://\";\n        public const string httpsProtocol = \"https://\";\n        public const string vlessProtocol = \"vless://\";\n        public const string vlessProtocolLite = \"vless\";\n        public const string trojanProtocol = \"trojan://\";\n        public const string trojanProtocolLite = \"trojan\";\n\n        public const string userEMail = \"t@t.tt\";\n        public const string MyRegPath = \"Software\\\\hiddifyNGUI\";\n        public const string AutoRunRegPath = @\"Software\\Microsoft\\Windows\\CurrentVersion\\Run\";\n        public const string AutoRunName = \"hiddifyNAutoRun\";\n        public const string MyRegKeyLanguage = \"CurrentLanguage\";\n        public const string CustomIconName = \"v2rayN.ico\";\n        public const string IEProxyExceptions = \"localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*\";\n        public const string RoutingRuleComma = \"<COMMA>\";\n        public const string GrpcgunMode = \"gun\";\n        public const string GrpcmultiMode = \"multi\";\n        public const int MaxPort = 65536;\n        public const string CommandClearMsg = \"CommandClearMsg\";\n        public const string DelayUnit = \"\";\n        public const string SpeedUnit = \"\";\n        public const int MinFontSize = 10;\n        public const string RebootAs = \"rebootas\";\n\n        public static readonly List<string> IEProxyProtocols = new() \n        {\n            \"{ip}:{http_port}\",\n            \"socks={ip}:{socks_port}\",\n            \"http={ip}:{http_port};https={ip}:{http_port};ftp={ip}:{http_port};socks={ip}:{socks_port}\",\n            \"http=http://{ip}:{http_port};https=http://{ip}:{http_port}\",\n            \"\"\n        };\n\n\n        public static readonly List<string> SubConvertUrls = new List<string> {\n                @\"https://sub.xeton.dev/sub?url={0}\",\n                @\"https://api.dler.io/sub?url={0}\",\n                @\"http://127.0.0.1:25500/sub?url={0}\",\n                \"\"\n            };\n\n        public static readonly List<string> SubConvertConfig = new List<string> {\n                @\"https://raw.githubusercontent.com/ACL4SSR/ACL4SSR/master/Clash/config/ACL4SSR_Online.ini\"\n            };\n\n        public static readonly List<string> SubConvertTargets = new List<string> {\n                \"\",\n                \"mixed\",\n                \"v2ray\",\n                \"clash\",\n                \"ss\",\n            };\n\n        public static readonly List<string> SpeedTestUrls = new() {\n            @\"http://cachefly.cachefly.net/100mb.test\",\n            @\"http://cachefly.cachefly.net/10mb.test\"\n        };\n\n        public static readonly Dictionary<string, string> userAgentTxt = new()\n        {\n            {\"chrome\",\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36\" },\n            {\"firefox\",\"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:90.0) Gecko/20100101 Firefox/90.0\" },\n            {\"safari\",\"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.1.1 Safari/605.1.15\" },\n            {\"edge\",\"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36 Edg/91.0.864.70\" },\n            {\"none\",\"\"}\n        };\n\n        public static readonly List<string> vmessSecuritys = new() { \"aes-128-gcm\", \"chacha20-poly1305\", \"auto\", \"none\", \"zero\" };\n        public static readonly List<string> ssSecuritys = new() { \"aes-256-gcm\", \"aes-128-gcm\", \"chacha20-poly1305\", \"chacha20-ietf-poly1305\", \"none\", \"plain\" };\n        public static readonly List<string> ssSecuritysInSagerNet = new() { \"none\", \"2022-blake3-aes-128-gcm\", \"2022-blake3-aes-256-gcm\", \"2022-blake3-chacha20-poly1305\", \"aes-128-gcm\", \"aes-192-gcm\", \"aes-256-gcm\", \"chacha20-ietf-poly1305\", \"xchacha20-ietf-poly1305\", \"rc4\", \"rc4-md5\", \"aes-128-ctr\", \"aes-192-ctr\", \"aes-256-ctr\", \"aes-128-cfb\", \"aes-192-cfb\", \"aes-256-cfb\", \"aes-128-cfb8\", \"aes-192-cfb8\", \"aes-256-cfb8\", \"aes-128-ofb\", \"aes-192-ofb\", \"aes-256-ofb\", \"bf-cfb\", \"cast5-cfb\", \"des-cfb\", \"idea-cfb\", \"rc2-cfb\", \"seed-cfb\", \"camellia-128-cfb\", \"camellia-192-cfb\", \"camellia-256-cfb\", \"camellia-128-cfb8\", \"camellia-192-cfb8\", \"camellia-256-cfb8\", \"salsa20\", \"chacha20\", \"chacha20-ietf\", \"xchacha20\" };\n        public static readonly List<string> ssSecuritysInXray = new() { \"aes-256-gcm\", \"aes-128-gcm\", \"chacha20-poly1305\", \"chacha20-ietf-poly1305\", \"xchacha20-poly1305\", \"xchacha20-ietf-poly1305\", \"none\", \"plain\", \"2022-blake3-aes-128-gcm\", \"2022-blake3-aes-256-gcm\", \"2022-blake3-chacha20-poly1305\" };\n        public static readonly List<string> flows = new() { \"\", \"xtls-rprx-vision\", \"xtls-rprx-vision-udp443\" };\n        public static readonly List<string> networks = new() { \"tcp\", \"kcp\", \"ws\", \"h2\", \"quic\", \"grpc\" };\n        public static readonly List<string> kcpHeaderTypes = new() { \"srtp\", \"utp\", \"wechat-video\", \"dtls\", \"wireguard\" };\n        public static readonly List<string> coreTypes = new() { \"v2fly\", \"SagerNet\", \"Xray\", \"v2fly_v5\", \"sing_box\" };\n        public static readonly List<string> coreTypes4VLESS = new() { \"Xray\", \"sing_box\" };\n        public static readonly List<string> domainStrategys = new() { \"AsIs\", \"IPIfNonMatch\", \"IPOnDemand\" };\n        public static readonly List<string> domainStrategys4Singbox = new() { \"ipv4_only\", \"ipv6_only\", \"prefer_ipv4\", \"prefer_ipv6\", \"\" };\n        public static readonly List<string> domainMatchers = new() { \"linear\", \"mph\", \"\" };\n        public static readonly List<string> fingerprints = new() { \"chrome\", \"firefox\", \"safari\", \"ios\", \"android\", \"edge\", \"360\", \"qq\", \"random\", \"randomized\", \"\" };\n        public static readonly List<string> userAgent = new() { \"chrome\", \"firefox\", \"safari\", \"edge\", \"none\" };\n\n        public static readonly List<string> allowInsecures = new() { \"true\", \"false\", \"\" };\n        public static readonly List<string> fragmentStrategies = new() { \"random\", \"sni\", \"\" };//hiddify\n        public static readonly List<string> domainStrategy4Freedoms = new() { \"AsIs\", \"UseIP\", \"UseIPv4\", \"UseIPv6\", \"\" };\n\n        public static readonly List<string> Languages = new() { \"en\", \"fa-Ir\", \"ru\", \"zh-Hans\"};\n        public static readonly List<string> alpns = new() { \"h2\", \"http/1.1\", \"h2,http/1.1\", \"\" };\n        public static readonly List<string> LogLevel = new() { \"debug\", \"info\", \"warning\", \"error\", \"none\" };\n        public static readonly List<string> InboundTags = new() { \"socks\", \"http\", \"socks2\", \"http2\" };\n        public static readonly List<string> Protocols = new() { \"http\", \"tls\", \"bittorrent\" };\n        public static readonly List<string> TunMtus = new() { \"9000\", \"1500\" };\n        public static readonly List<string> TunStacks = new() { \"gvisor\", \"system\" };\n        public static readonly List<string> PresetMsgFilters = new() { \"proxy\", \"direct\", \"block\", \"\" };\n\n        #endregion const\n\n        #region global variable\n\n        public static int statePort { get; set; }\n        public static Job processJob { get; set; }\n        public static bool ShowInTaskbar { get; set; }\n        public static string ExePathKey { get; set; }\n\n        public static string MainFormReloadFilePath { get; set; } = Utils.GetTempPath(\"mainPageReloadLockFile.txt\");\n        public static readonly string RestartProgramExePath = Path.GetFullPath(Path.Combine(Utils.StartupPath(), \"bin\", \"hiddifyRestartN\", \"HiddifyRestartN.exe\"));\n        public static readonly string UpgradeProgramExePath = Path.GetFullPath(Path.Combine(Utils.StartupPath(), \"bin\", \"hiddifyUpgradeN\", \"HiddifyUpgradeN.exe\"));\n        public static readonly string SpeedTestProgramExePath = Path.GetFullPath(Path.Combine(Utils.StartupPath(), \"bin\", \"speedTest\", \"librespeed-cli.exe\"));\n\n        #endregion global variable\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/ConfigHandler.cs",
    "content": "﻿using Splat;\nusing System.Collections.Specialized;\nusing System.Data;\nusing System.IO;\nusing System.Security.Policy;\nusing System.Text.RegularExpressions;\nusing v2rayN.Base;\nusing v2rayN.Mode;\nusing v2rayN.Tool;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Handler\n{\n    /// <summary>\n    /// 本软件配置文件处理类\n    /// </summary>\n    internal class ConfigHandler\n    {\n        private static string configRes = Global.ConfigFileName;\n        private static readonly object objLock = new();\n\n        #region ConfigHandler\n\n        /// <summary>\n        /// 载入配置文件\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <returns></returns>\n        public static int LoadConfig(ref Config config)\n        {\n            //载入配置文件\n            string result = Utils.LoadResource(Utils.GetConfigPath(configRes));\n            if (!Utils.IsNullOrEmpty(result))\n            {\n                //转成Json\n                config = Utils.FromJson<Config>(result);\n            }\n            else\n            {\n                if (File.Exists(Utils.GetConfigPath(configRes)))\n                {\n                    Utils.SaveLog(\"LoadConfig Exception\");\n                    return -1;\n                }\n            }\n\n            if (config == null)\n            {\n                config = new Config\n                {\n                };\n            }\n            if (config.coreBasicItem == null)\n            {\n                config.coreBasicItem = new()\n                {\n                    logEnabled = false,\n                    loglevel = \"warning\",\n\n                    muxEnabled = false,\n                };\n            }\n\n            //本地监听\n            if (config.inbound == null)\n            {\n                config.inbound = new List<InItem>();\n                InItem inItem = new()\n                {\n                    protocol = Global.InboundSocks,\n                    localPort = 10808,\n                    udpEnabled = true,\n                    sniffingEnabled = true,\n                    routeOnly = false,\n                };\n\n                config.inbound.Add(inItem);\n\n                //inItem = new InItem();\n                //inItem.protocol = \"http\";\n                //inItem.localPort = 1081;\n                //inItem.udpEnabled = true;\n\n                //config.inbound.Add(inItem);\n            }\n            else\n            {\n                if (config.inbound.Count > 0)\n                {\n                    config.inbound[0].protocol = Global.InboundSocks;\n                }\n            }\n            if (config.routingBasicItem == null)\n            {\n                config.routingBasicItem = new()\n                {\n                    enableRoutingAdvanced = true\n                };\n            }\n            //路由规则\n            if (Utils.IsNullOrEmpty(config.routingBasicItem.domainStrategy))\n            {\n                config.routingBasicItem.domainStrategy = Global.domainStrategys[0];//\"IPIfNonMatch\";\n            }\n            //if (Utils.IsNullOrEmpty(config.domainMatcher))\n            //{\n            //    config.domainMatcher = \"linear\";\n            //}\n\n            //kcp\n            if (config.kcpItem == null)\n            {\n                config.kcpItem = new KcpItem\n                {\n                    mtu = 1350,\n                    tti = 50,\n                    uplinkCapacity = 12,\n                    downlinkCapacity = 100,\n                    readBufferSize = 2,\n                    writeBufferSize = 2,\n                    congestion = false\n                };\n            }\n            if (config.grpcItem == null)\n            {\n                config.grpcItem = new GrpcItem\n                {\n                    idle_timeout = 60,\n                    health_check_timeout = 20,\n                    permit_without_stream = false,\n                    initial_windows_size = 0,\n                };\n            }\n            if (config.tunModeItem == null)\n            {\n                config.tunModeItem = new TunModeItem\n                {\n                    enableTun = false,\n                    showWindow = true,\n                    mtu = 9000,\n                };\n            }\n            if (config.guiItem == null)\n            {\n                config.guiItem = new()\n                {\n                    enableStatistics = false,\n                    statisticsFreshRate = 1,\n                };\n            }\n            if (config.uiItem == null)\n            {\n                config.uiItem = new UIItem()\n                {\n                    enableAutoAdjustMainLvColWidth = true\n                };\n            }\n            if (config.uiItem.mainColumnItem == null)\n            {\n                config.uiItem.mainColumnItem = new();\n            }\n            if (Utils.IsNullOrEmpty(config.uiItem.currentLanguage))\n            {\n                config.uiItem.currentLanguage = Global.Languages[0];\n            }\n\n            if (config.constItem == null)\n            {\n                config.constItem = new ConstItem();\n            }\n            if (Utils.IsNullOrEmpty(config.constItem.defIEProxyExceptions))\n            {\n                config.constItem.defIEProxyExceptions = Global.IEProxyExceptions;\n            }\n\n            if (config.speedTestItem == null)\n            {\n                config.speedTestItem = new();\n            }\n            if (config.speedTestItem.speedTestTimeout < 10)\n            {\n                config.speedTestItem.speedTestTimeout = 10;\n            }\n            if (Utils.IsNullOrEmpty(config.speedTestItem.speedTestUrl))\n            {\n                config.speedTestItem.speedTestUrl = Global.SpeedTestUrls[0];\n            }\n            //if (Utils.IsNullOrEmpty(config.speedTestItem.speedPingTestUrl))\n            {\n                config.speedTestItem.speedPingTestUrl = Global.SpeedPingTestUrlGoogle;\n            }\n\n            if (config.guiItem.statisticsFreshRate is > 100 or < 1)\n            {\n                config.guiItem.statisticsFreshRate = 1;\n            }\n\n            LazyConfig.Instance.SetConfig(config);\n            return 0;\n        }\n\n        /// <summary>\n        /// 保参数\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <returns></returns>\n        public static int SaveConfig(ref Config config, bool reload = true)\n        {\n            ToJsonFile(config);\n\n            return 0;\n        }\n\n        /// <summary>\n        /// 存储文件\n        /// </summary>\n        /// <param name=\"config\"></param>\n        private static void ToJsonFile(Config config)\n        {\n            lock (objLock)\n            {\n                try\n                {\n                    //save temp file\n                    var resPath = Utils.GetConfigPath(configRes);\n                    var tempPath = $\"{resPath}_temp\";\n                    if (Utils.ToJsonFile(config, tempPath) != 0)\n                    {\n                        return;\n                    }\n\n                    if (File.Exists(resPath))\n                    {\n                        File.Delete(resPath);\n                    }\n                    //rename\n                    File.Move(tempPath, resPath);\n                }\n                catch (Exception ex)\n                {\n                    Utils.SaveLog(\"ToJsonFile\", ex);\n                }\n            }\n        }\n\n        public static int ImportOldGuiConfig(ref Config config, string fileName)\n        {\n            string result = Utils.LoadResource(fileName);\n            if (Utils.IsNullOrEmpty(result))\n            {\n                return -1;\n            }\n\n            var configOld = Utils.FromJson<ConfigOld>(result);\n            if (configOld == null)\n            {\n                return -1;\n            }\n\n            var subItem = Utils.FromJson<List<SubItem>>(Utils.ToJson(configOld.subItem));\n            foreach (var it in subItem)\n            {\n                if (Utils.IsNullOrEmpty(it.id))\n                {\n                    it.id = Utils.GetGUID(false);\n                }\n                SqliteHelper.Instance.Replace(it);\n            }\n\n            var profileItems = Utils.FromJson<List<ProfileItem>>(Utils.ToJson(configOld.vmess));\n            foreach (var it in profileItems)\n            {\n                if (Utils.IsNullOrEmpty(it.indexId))\n                {\n                    it.indexId = Utils.GetGUID(false);\n                }\n                SqliteHelper.Instance.Replace(it);\n            }\n\n            foreach (var it in configOld.routings)\n            {\n                if (it.locked)\n                {\n                    continue;\n                }\n                var routing = Utils.FromJson<RoutingItem>(Utils.ToJson(it));\n                foreach (var it2 in it.rules)\n                {\n                    it2.id = Utils.GetGUID(false);\n                }\n                routing.ruleNum = it.rules.Count;\n                routing.ruleSet = Utils.ToJson(it.rules, false);\n\n                if (Utils.IsNullOrEmpty(routing.id))\n                {\n                    routing.id = Utils.GetGUID(false);\n                }\n                SqliteHelper.Instance.Replace(routing);\n            }\n\n            config = Utils.FromJson<Config>(Utils.ToJson(configOld));\n\n            if (config.coreBasicItem == null)\n            {\n                config.coreBasicItem = new()\n                {\n                    logEnabled = configOld.logEnabled,\n                    loglevel = configOld.loglevel,\n                    muxEnabled = configOld.muxEnabled,\n                };\n            }\n\n            if (config.routingBasicItem == null)\n            {\n                config.routingBasicItem = new()\n                {\n                    enableRoutingAdvanced = configOld.enableRoutingAdvanced,\n                    domainStrategy = configOld.domainStrategy\n                };\n            }\n\n            if (config.guiItem == null)\n            {\n                config.guiItem = new()\n                {\n                    enableStatistics = configOld.enableStatistics,\n                    statisticsFreshRate = configOld.statisticsFreshRate,\n                    keepOlderDedupl = configOld.keepOlderDedupl,\n                    ignoreGeoUpdateCore = configOld.ignoreGeoUpdateCore,\n                    autoUpdateInterval = configOld.autoUpdateInterval,\n                    checkPreReleaseUpdate = configOld.checkPreReleaseUpdate,\n                    enableSecurityProtocolTls13 = configOld.enableSecurityProtocolTls13,\n                    trayMenuServersLimit = configOld.trayMenuServersLimit,\n                };\n            }\n\n            GetDefaultServer(ref config);\n            GetDefaultRouting(ref config);\n            SaveConfig(ref config);\n            LoadConfig(ref config);\n\n            return 0;\n        }\n\n        #endregion ConfigHandler\n\n        #region Server\n\n        /// <summary>\n        /// 添加服务器或编辑\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"profileItem\"></param>\n        /// <returns></returns>\n        public static int AddServer(ref Config config, ProfileItem profileItem, bool toFile = true)\n        {\n            profileItem.configType = EConfigType.VMess;\n\n            profileItem.address = profileItem.address.TrimEx();\n            profileItem.id = profileItem.id.TrimEx();\n            profileItem.security = profileItem.security.TrimEx();\n            profileItem.network = profileItem.network.TrimEx();\n            profileItem.headerType = profileItem.headerType.TrimEx();\n            profileItem.requestHost = profileItem.requestHost.TrimEx();\n            profileItem.path = profileItem.path.TrimEx();\n            profileItem.streamSecurity = profileItem.streamSecurity.TrimEx();\n\n            if (!Global.vmessSecuritys.Contains(profileItem.security))\n            {\n                return -1;\n            }\n\n            AddServerCommon(ref config, profileItem, toFile);\n            \n            return 0;\n        }\n\n        /// <summary>\n        /// 移除服务器\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"indexs\"></param>\n        /// <returns></returns>\n        public static int RemoveServer(Config config, List<ProfileItem> indexs)\n        {\n            var subid = \"TempRemoveSubId\";\n            foreach (var item in indexs)\n            {\n                item.subid = subid;\n            }\n\n            SqliteHelper.Instance.UpdateAll(indexs);\n            RemoveServerViaSubid(ref config, subid, false);\n\n            return 0;\n        }\n\n        /// <summary>\n        /// 克隆服务器\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"index\"></param>\n        /// <returns></returns>\n        public static int CopyServer(ref Config config, List<ProfileItem> indexs)\n        {\n            foreach (var it in indexs)\n            {\n                var item = LazyConfig.Instance.GetProfileItem(it.indexId);\n                if (item is null)\n                {\n                    continue;\n                }\n\n                ProfileItem profileItem = Utils.DeepCopy(item);\n                profileItem.indexId = string.Empty;\n                profileItem.remarks = $\"{item.remarks}-clone\";\n\n                if (profileItem.configType == EConfigType.Custom)\n                {\n                    profileItem.address = Utils.GetConfigPath(profileItem.address);\n                    if (AddCustomServer(ref config, profileItem, false) == 0)\n                    {\n                    }\n                }\n                else\n                {\n                    AddServerCommon(ref config, profileItem, true);\n                }\n            }\n\n            return 0;\n        }\n\n        /// <summary>\n        /// 设置活动服务器\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"item\"></param>\n        /// <returns></returns>\n        public static int SetDefaultServerIndex(ref Config config, string? indexId)\n        {\n            if (Utils.IsNullOrEmpty(indexId))\n            {\n                return -1;\n            }\n\n            config.indexId = indexId;\n\n            ToJsonFile(config);\n\n            return 0;\n        }\n\n        public static int SetDefaultServer(Config config, List<ProfileItemModel> lstProfile)\n        {\n            if (lstProfile.Exists(t => t.indexId == config.indexId))\n            {\n                return 0;\n            }\n            if (SqliteHelper.Instance.Table<ProfileItem>().Where(t => t.indexId == config.indexId).Any())\n            {\n                return 0;\n            }\n            if (lstProfile.Count > 0)\n            {\n                return SetDefaultServerIndex(ref config, lstProfile.Where(t => t.port > 0).FirstOrDefault()?.indexId);\n            }\n            return SetDefaultServerIndex(ref config, SqliteHelper.Instance.Table<ProfileItem>().Where(t => t.port > 0).Select(t => t.indexId).FirstOrDefault());\n        }\n\n        public static ProfileItem? GetDefaultServer(ref Config config)\n        {\n            var item = LazyConfig.Instance.GetProfileItem(config.indexId);\n            if (item is null)\n            {\n                var item2 = SqliteHelper.Instance.Table<ProfileItem>().FirstOrDefault();\n                SetDefaultServerIndex(ref config, item2?.indexId);\n                return item2;\n            }\n\n            return item;\n        }\n\n        /// <summary>\n        /// 移动服务器\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"lstProfile\"></param>\n        /// <param name=\"index\"></param>\n        /// <param name=\"eMove\"></param>\n        /// <returns></returns>\n        public static int MoveServer(ref Config config, ref List<ProfileItem> lstProfile, int index, EMove eMove, int pos = -1)\n        {\n            int count = lstProfile.Count;\n            if (index < 0 || index > lstProfile.Count - 1)\n            {\n                return -1;\n            }\n\n            for (int i = 0; i < lstProfile.Count; i++)\n            {\n                ProfileExHandler.Instance.SetSort(lstProfile[i].indexId, (i + 1) * 10);\n            }\n\n            var sort = 0;\n            switch (eMove)\n            {\n                case EMove.Top:\n                    {\n                        if (index == 0)\n                        {\n                            return 0;\n                        }\n                        sort = ProfileExHandler.Instance.GetSort(lstProfile[0].indexId) - 1;\n\n                        break;\n                    }\n                case EMove.Up:\n                    {\n                        if (index == 0)\n                        {\n                            return 0;\n                        }\n                        sort = ProfileExHandler.Instance.GetSort(lstProfile[index - 1].indexId) - 1;\n\n                        break;\n                    }\n\n                case EMove.Down:\n                    {\n                        if (index == count - 1)\n                        {\n                            return 0;\n                        }\n                        sort = ProfileExHandler.Instance.GetSort(lstProfile[index + 1].indexId) + 1;\n\n                        break;\n                    }\n                case EMove.Bottom:\n                    {\n                        if (index == count - 1)\n                        {\n                            return 0;\n                        }\n                        sort = ProfileExHandler.Instance.GetSort(lstProfile[^1].indexId) + 1;\n\n                        break;\n                    }\n                case EMove.Position:\n                    sort = pos * 10 + 1;\n                    break;\n            }\n\n            ProfileExHandler.Instance.SetSort(lstProfile[index].indexId, sort);\n            return 0;\n        }\n\n        /// <summary>\n        /// 添加自定义服务器\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"profileItem\"></param>\n        /// <returns></returns>\n        public static int AddCustomServer(ref Config config, ProfileItem profileItem, bool blDelete)\n        {\n            var fileName = profileItem.address;\n            if (!File.Exists(fileName))\n            {\n                return -1;\n            }\n            var ext = Path.GetExtension(fileName);\n            string newFileName = $\"{Utils.GetGUID()}{ext}\";\n            //newFileName = Path.Combine(Utils.GetTempPath(), newFileName);\n\n            try\n            {\n                File.Copy(fileName, Utils.GetConfigPath(newFileName));\n                if (blDelete)\n                {\n                    File.Delete(fileName);\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                return -1;\n            }\n\n            profileItem.address = newFileName;\n            profileItem.configType = EConfigType.Custom;\n            if (Utils.IsNullOrEmpty(profileItem.remarks))\n            {\n                profileItem.remarks = $\"import custom@{DateTime.Now.ToShortDateString()}\";\n            }\n\n            AddServerCommon(ref config, profileItem, true);\n\n            return 0;\n        }\n\n        /// <summary>\n        /// 添加服务器或编辑\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"profileItem\"></param>\n        /// <returns></returns>\n        public static int EditCustomServer(ref Config config, ProfileItem profileItem)\n        {\n            if (SqliteHelper.Instance.Update(profileItem) > 0)\n            {\n                return 0;\n            }\n            else\n            {\n                return -1;\n            }\n\n            //ToJsonFile(config);\n        }\n\n        /// <summary>\n        /// 添加服务器或编辑\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"profileItem\"></param>\n        /// <returns></returns>\n        public static int AddShadowsocksServer(ref Config config, ProfileItem profileItem, bool toFile = true)\n        {\n            profileItem.configType = EConfigType.Shadowsocks;\n\n            profileItem.address = profileItem.address.TrimEx();\n            profileItem.id = profileItem.id.TrimEx();\n            profileItem.security = profileItem.security.TrimEx();\n\n            if (!LazyConfig.Instance.GetShadowsocksSecuritys(profileItem).Contains(profileItem.security))\n            {\n                return -1;\n            }\n\n            AddServerCommon(ref config, profileItem, toFile);\n\n            return 0;\n        }\n\n        /// <summary>\n        /// 添加服务器或编辑\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"profileItem\"></param>\n        /// <returns></returns>\n        public static int AddSocksServer(ref Config config, ProfileItem profileItem, bool toFile = true)\n        {\n            profileItem.configType = EConfigType.Socks;\n\n            profileItem.address = profileItem.address.TrimEx();\n\n            AddServerCommon(ref config, profileItem, toFile);\n\n            return 0;\n        }\n\n        /// <summary>\n        /// 添加服务器或编辑\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"profileItem\"></param>\n        /// <returns></returns>\n        public static int AddTrojanServer(ref Config config, ProfileItem profileItem, bool toFile = true)\n        {\n            profileItem.configType = EConfigType.Trojan;\n\n            profileItem.address = profileItem.address.TrimEx();\n            profileItem.id = profileItem.id.TrimEx();\n            if (Utils.IsNullOrEmpty(profileItem.streamSecurity))\n            {\n                profileItem.streamSecurity = Global.StreamSecurity;\n            }\n\n            AddServerCommon(ref config, profileItem, toFile);\n\n            return 0;\n        }\n\n        public static int SortServers(ref Config config, string subId, string colName, bool asc)\n        {\n            var lstModel = LazyConfig.Instance.ProfileItems(subId, \"\");\n            if (lstModel.Count <= 0)\n            {\n                return -1;\n            }\n            var lstProfileExs = ProfileExHandler.Instance.ProfileExs;\n            var lstProfile = (from t in lstModel\n                              join t3 in lstProfileExs on t.indexId equals t3.indexId into t3b\n                              from t33 in t3b.DefaultIfEmpty()\n                              select new ProfileItemModel\n                              {\n                                  indexId = t.indexId,\n                                  configType = t.configType,\n                                  remarks = t.remarks,\n                                  address = t.address,\n                                  port = t.port,\n                                  security = t.security,\n                                  network = t.network,\n                                  streamSecurity = t.streamSecurity,\n                                  delay = t33 == null ? 0 : t33.delay,\n                                  speed = t33 == null ? 0 : t33.speed,\n                                  sort = t33 == null ? 0 : t33.sort\n                              }).ToList();\n\n            Enum.TryParse(colName, true, out EServerColName name);\n            var propertyName = string.Empty;\n            switch (name)\n            {\n                case EServerColName.configType:\n                case EServerColName.remarks:\n                case EServerColName.address:\n                case EServerColName.port:\n                case EServerColName.security:\n                case EServerColName.network:\n                case EServerColName.streamSecurity:\n                    propertyName = name.ToString();\n                    break;\n\n                case EServerColName.delayVal:\n                    propertyName = \"delay\";\n                    break;\n\n                case EServerColName.speedVal:\n                    propertyName = \"speed\";\n                    break;\n\n                case EServerColName.subRemarks:\n                    propertyName = \"subid\";\n                    break;\n\n                default:\n                    //return -1;\n                    propertyName = \"indexId\";\n                    break;\n            }\n\n            var items = lstProfile.AsQueryable();\n\n\n            if (asc)\n            {\n                lstProfile = items.OrderBy(propertyName).ToList();\n\n            }\n            else\n            {\n                lstProfile = items.OrderByDescending(propertyName).ToList();\n            }\n            var lbi = lstProfile.FirstOrDefault(p => p.configType == EConfigType.LoadBalance);\n            if (lbi != null)\n            {\n                lstProfile.Remove(lbi);\n                lstProfile.Insert(0, lbi);\n            }\n            var lpi = lstProfile.FirstOrDefault(p => p.configType == EConfigType.LowestPing);\n            if (lpi != null)\n            {\n                lstProfile.Remove(lpi);\n                lstProfile.Insert(0, lpi);\n            }\n            var usagei = lstProfile.FirstOrDefault(p => p.configType == EConfigType.Usage);\n            if (usagei != null)\n            {\n                lstProfile.Remove(usagei);\n                lstProfile.Insert(0, usagei);\n            }\n            for (int i = 0; i < lstProfile.Count; i++)\n            {\n                ProfileExHandler.Instance.SetSort(lstProfile[i].indexId, (i + 1) * 10);\n            }\n            if (name == EServerColName.delayVal)\n            {\n                var maxSort = lstProfile.Max(t => t.sort) + 10;\n                foreach (var item in lstProfile)\n                {\n                    if (item.delay <= 0)\n                    {\n                        ProfileExHandler.Instance.SetSort(item.indexId, maxSort);\n                    }\n                }\n            }\n            if (name == EServerColName.speedVal)\n            {\n                var maxSort = lstProfile.Max(t => t.sort) + 10;\n                foreach (var item in lstProfile)\n                {\n                    if (item.speed <= 0)\n                    {\n                        ProfileExHandler.Instance.SetSort(item.indexId, maxSort);\n                    }\n                }\n            }\n\n            return 0;\n        }\n        class CustomComparer : IComparer<ProfileItem>\n        {\n            CustomComparer(String property)\n            {\n\n            }\n            public int Compare(ProfileItem a, ProfileItem b)\n            {\n                if ((int)a.configType > 100 && (int)b.configType < 100)\n                    return -1;\n                if ((int)a.configType < 100 && (int)b.configType > 100)\n                    return 1;\n                if ((int)a.configType > 100 && (int)b.configType > 100)\n                    return (int)a.configType - (int)b.configType;\n                return 0;\n                //return positive if a should be higher, return negative if b should be higher\n            }\n        }\n        /// <summary>\n        /// 添加服务器或编辑\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"profileItem\"></param>\n        /// <returns></returns>\n        public static int AddVlessServer(ref Config config, ProfileItem profileItem, bool toFile = true)\n        {\n            profileItem.configType = EConfigType.VLESS;\n\n            profileItem.address = profileItem.address.TrimEx();\n            profileItem.id = profileItem.id.TrimEx();\n            profileItem.security = profileItem.security.TrimEx();\n            profileItem.network = profileItem.network.TrimEx();\n            profileItem.headerType = profileItem.headerType.TrimEx();\n            profileItem.requestHost = profileItem.requestHost.TrimEx();\n            profileItem.path = profileItem.path.TrimEx();\n            profileItem.streamSecurity = profileItem.streamSecurity.TrimEx();\n\n            if (!Global.flows.Contains(profileItem.flow))\n            {\n                profileItem.flow = Global.flows.First();\n            }\n\n            AddServerCommon(ref config, profileItem, toFile);\n\n            return 0;\n        }\n\n        public static Tuple<int, int> DedupServerList(Config config, string subId)\n        {\n            var lstProfile = LazyConfig.Instance.ProfileItems(subId);\n\n            List<ProfileItem> lstKeep = new();\n            List<ProfileItem> lstRemove = new();\n            if (!config.guiItem.keepOlderDedupl) lstProfile.Reverse();\n\n            foreach (ProfileItem item in lstProfile)\n            {\n                if (!lstKeep.Exists(i => CompareProfileItem(i, item, false)))\n                {\n                    lstKeep.Add(item);\n                }\n                else\n                {\n                    lstRemove.Add(item);\n                }\n            }\n            RemoveServer(config, lstRemove);\n\n            return new Tuple<int, int>(lstProfile.Count, lstKeep.Count);\n        }\n\n        public static int AddServerCommon(ref Config config, ProfileItem profileItem, bool toFile = true)\n        {\n            profileItem.configVersion = 2;\n\n            if (!Utils.IsNullOrEmpty(profileItem.streamSecurity))\n            {\n                if (Utils.IsNullOrEmpty(profileItem.allowInsecure))\n                {\n                    profileItem.allowInsecure = config.coreBasicItem.defAllowInsecure.ToString().ToLower();\n                }\n                if (Utils.IsNullOrEmpty(profileItem.fingerprint))\n                {\n                    profileItem.fingerprint = config.coreBasicItem.defFingerprint;\n                }\n            }\n\n            if (!Utils.IsNullOrEmpty(profileItem.network) && !Global.networks.Contains(profileItem.network))\n            {\n                profileItem.network = Global.DefaultNetwork;\n            }\n\n            if (Utils.IsNullOrEmpty(profileItem.indexId))\n            {\n                profileItem.indexId = Utils.GetGUID(false);\n                var maxSort = ProfileExHandler.Instance.GetMaxSort();\n                ProfileExHandler.Instance.SetSort(profileItem.indexId, maxSort + 1);\n            }\n\n            if (toFile)\n            {\n                SqliteHelper.Instance.Replace(profileItem);\n            }\n            return 0;\n        }\n\n        private static bool CompareProfileItem(ProfileItem o, ProfileItem n, bool remarks)\n        {\n            if (o == null || n == null)\n            {\n                return false;\n            }\n\n            return o.configType == n.configType\n                && o.address == n.address\n                && o.port == n.port\n                && o.id == n.id\n                && o.alterId == n.alterId\n                && o.security == n.security\n                && o.network == n.network\n                && o.headerType == n.headerType\n                && o.requestHost == n.requestHost\n                && o.path == n.path\n                && (o.configType == EConfigType.Trojan || o.streamSecurity == n.streamSecurity)\n                && o.flow == n.flow\n                && o.sni == n.sni\n                && (!remarks || o.remarks == n.remarks);\n        }\n\n        private static int RemoveProfileItem(Config config, string indexId)\n        {\n            try\n            {\n                var item = LazyConfig.Instance.GetProfileItem(indexId);\n                if (item == null)\n                {\n                    return 0;\n                }\n                if (item.configType == EConfigType.Custom)\n                {\n                    File.Delete(Utils.GetConfigPath(item.address));\n                }\n\n                SqliteHelper.Instance.Delete(item);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(\"Remove Item\", ex);\n            }\n\n            return 0;\n        }\n\n        #endregion Server\n\n        #region Batch add servers\n\n        /// <summary>\n        /// 批量添加服务器\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"clipboardData\"></param>\n        /// <param name=\"subid\"></param>\n        /// <returns>成功导入的数量</returns>\n        private static int AddBatchServers(ref Config config, string clipboardData, string subid, bool isSub, List<ProfileItem> lstOriSub)\n        {\n            if (Utils.IsNullOrEmpty(clipboardData))\n            {\n                return -1;\n            }\n\n            string subFilter = string.Empty;\n            //remove sub items\n            if (isSub && !Utils.IsNullOrEmpty(subid))\n            {\n                RemoveServerViaSubid(ref config, subid, isSub);\n                subFilter = LazyConfig.Instance.GetSubItem(subid)?.filter ?? \"\";\n                var subitem = LazyConfig.Instance.GetSubItem(subid);\n            }\n\n            int countServers = 0;\n            //Check for duplicate indexId\n            List<string>? lstDbIndexId = null;\n            List<ProfileItem> lstAdd = new();\n            var arrData = clipboardData.Split(Environment.NewLine.ToCharArray()).Where(t => !t.IsNullOrEmpty());\n            if (isSub)\n            {\n                arrData = arrData.Distinct();\n            }\n            foreach (string str in arrData)\n            {\n                //maybe sub\n                if (!isSub && (str.StartsWith(Global.httpsProtocol) || str.StartsWith(Global.httpProtocol)))\n                {\n                    //// It's a custom feature for this app (probably none of your business)\n                    //string? panelAddress = Utils.GetHostAndFirstTwoPathInUri(str);\n                    //// If we can't get panel address we just put host address in there\n                    //if (panelAddress == null)\n                    //{\n                    //    panelAddress = new Uri(str).Host;\n                    //}\n\n                    // WE SAVE THIS INFORMATION IN SubItem ITSELF (NOT AS ROW/SERVER)\n                    //var usageItem = new ProfileItem()\n                    //{\n                    //    configType = EConfigType.Usage,\n                    //    remarks = $\"{userSubInfo.DownloadAndUploadTotalGigaBytes()}GB/{userSubInfo.TotalGigaBytes()}GB \",\n                    //    security = $\"Expire in {userSubInfo.DaysLeftToExpire()} days\",\n                    //    // Direct panel address\n                    //    address = panelAddress,\n                    //    coreType = ECoreType.Xray,\n                    //    subid = subid\n                    //};\n                    //AddServerCommon(ref config, usageItem, false);\n\n                    var LowestPingItem = new ProfileItem()\n                    {\n                        configType = EConfigType.LowestPing,\n                        remarks = \"Lowest Ping\",\n                        address = \"All\",\n                        coreType = ECoreType.Xray,\n                        subid = subid\n                    };\n                    AddServerCommon(ref config, LowestPingItem, false);\n                    var loadBalanceItem = new ProfileItem()\n                    {\n                        configType = EConfigType.LoadBalance,\n                        remarks = \"Load Balance\",\n                        address = \"All\",\n                        coreType = ECoreType.Xray,\n                        subid = subid\n                    };\n                    AddServerCommon(ref config, loadBalanceItem, false);\n\n\n                    var subName = Utils.ExtractNameParameterFromUri(str);\n\n                    // If it's sub, We get remaining day to expire & used data & total remained data & profile web page url\n                    // We add this information as a Server but these's just for display to user for their information\n\n                    // Get user subscription info (like donwloaded/uploaded/total usage and expire date)\n                    // Get expire epoch date\n                    var headers = Utils.GetUrlResponseHeader(str,false);\n                    var subInfo = Utils.GetSubscriptionInfoFromHeaders(headers);\n                    //if (subInfo == null)\n                    //{\n                    //    // Handle error\n                    //}\n                    SubItem subscriptionItem = new SubItem();\n                    subscriptionItem.id = Utils.GetGUID(false);\n                    subscriptionItem.remarks = subName;\n                    if (subInfo != null)\n                    {\n                        subscriptionItem.upload = subInfo.Upload;\n                        subscriptionItem.download = subInfo.Download;\n                        subscriptionItem.total = subInfo.Total;\n                        subscriptionItem.expireDate = subInfo.ExpireDate;\n                        subscriptionItem.remaningExpireDays = subscriptionItem.DaysLeftToExpire();\n                        subscriptionItem.UsedDataGB = subscriptionItem.UsedDataGigaBytes();\n                        subscriptionItem.TotalDataGB = subscriptionItem.TotalDataGigaBytes();\n                        subscriptionItem.profileWebPageUrl = subInfo.ProfileWebPageUrl;\n                        if (!subInfo.ProfileTitle.IsNullOrWhiteSpace())\n                        {\n                            subscriptionItem.remarks = subInfo.ProfileTitle ?? \"\";\n                            if (subscriptionItem.remarks.StartsWith(\"base64:\")){\n                                subscriptionItem.remarks = Utils.Base64Decode(subscriptionItem.remarks.Substring(\"base64:\".Length));\n                            }\n                        }\n                        \n                    }\n\n                    if (subscriptionItem.remarks != null)\n                    {\n                        if (AddSubItem(ref config, subscriptionItem) == 0)\n                        {\n                            countServers++;\n                        }\n                    }\n                    continue;\n                }\n\n                // Add server(s)\n                ProfileItem profileItem = ShareHandler.ImportFromClipboardConfig(str, out string msg);\n                if (profileItem == null)\n                {\n                    continue;\n                }\n\n                //exist sub items\n                if (isSub && !Utils.IsNullOrEmpty(subid))\n                {\n                    var existItem = lstOriSub?.FirstOrDefault(t => t.isSub == isSub && CompareProfileItem(t, profileItem, true));\n                    if (existItem != null)\n                    {\n                        //Check for duplicate indexId\n                        if (lstDbIndexId is null)\n                        {\n                            lstDbIndexId = LazyConfig.Instance.ProfileItemIndexs(\"\");\n                        }\n                        if (lstAdd.Any(t => t.indexId == existItem.indexId)\n                            || lstDbIndexId.Any(t => t == existItem.indexId))\n                        {\n                            profileItem.indexId = string.Empty;\n                        }\n                        else\n                        {\n                            profileItem.indexId = existItem.indexId;\n                        }\n                    }\n                    //filter\n                    if (!Utils.IsNullOrEmpty(subFilter))\n                    {\n                        if (!Regex.IsMatch(profileItem.remarks, subFilter))\n                        {\n                            continue;\n                        }\n                    }\n                }\n                profileItem.subid = subid;\n                profileItem.isSub = isSub;\n                var addStatus = -1;\n\n                if (profileItem.configType == EConfigType.VMess)\n                {\n                    addStatus = AddServer(ref config, profileItem, false);\n                }\n                else if (profileItem.configType == EConfigType.Shadowsocks)\n                {\n                    addStatus = AddShadowsocksServer(ref config, profileItem, false);\n                }\n                else if (profileItem.configType == EConfigType.Socks)\n                {\n                    addStatus = AddSocksServer(ref config, profileItem, false);\n                }\n                else if (profileItem.configType == EConfigType.Trojan)\n                {\n                    addStatus = AddTrojanServer(ref config, profileItem, false);\n                }\n                else if (profileItem.configType == EConfigType.VLESS)\n                {\n                    addStatus = AddVlessServer(ref config, profileItem, false);\n                }\n\n                if (addStatus == 0 && profileItem.port > 0)\n                {\n                    if (countServers == 0)\n                    {\n                        //                        lstAdd.Add(usageItem);\n                        var LowestPingItem = new ProfileItem()\n                        {\n                            configType = EConfigType.LowestPing,\n                            remarks = \"Lowest Ping\",\n                            address = \"All\",\n                            coreType = ECoreType.Xray,\n                            subid = subid,\n                            indexId = \"0\" + new Random().Next(0, 10000000)\n                        };\n                        AddServerCommon(ref config, LowestPingItem, false);\n                        var loadBalanceItem = new ProfileItem()\n                        {\n                            configType = EConfigType.LoadBalance,\n                            remarks = \"Load Balance\",\n                            address = \"All\",\n                            coreType = ECoreType.Xray,\n                            subid = subid,\n                            indexId = \"1\" + new Random().Next(0, 10000000)\n                        };\n                        AddServerCommon(ref config, loadBalanceItem, false);\n                        lstAdd.Add(LowestPingItem);\n                        lstAdd.Add(loadBalanceItem);\n                    }\n                    countServers++;\n                    lstAdd.Add(profileItem);\n                }\n            }\n\n            if (lstAdd.Count > 0)\n            {\n                SqliteHelper.Instance.InsertAll(lstAdd);\n            }\n\n            ToJsonFile(config);\n            return countServers;\n        }\n\n        public static (int,List<string>) HomeAddBatchServers(ref Config config, string clipboardData, string subid, bool isSub, List<ProfileItem> lstOriSub)\n        {\n            List<string> addedSubIds = new();\n\n            if (Utils.IsNullOrEmpty(clipboardData))\n            {\n                return (-1, addedSubIds);\n            }\n\n            string subFilter = string.Empty;\n            //remove sub items\n            if (isSub && !Utils.IsNullOrEmpty(subid))\n            {\n                RemoveServerViaSubid(ref config, subid, isSub);\n                subFilter = LazyConfig.Instance.GetSubItem(subid)?.filter ?? \"\";\n                var subitem = LazyConfig.Instance.GetSubItem(subid);\n            }\n\n            int countServers = 0;\n\n            // We keep servers in this variable to add and join them to new sub\n            List<ProfileItem> servers = new();\n\n            string[] arrData = clipboardData.Split(Environment.NewLine.ToCharArray());\n            foreach (string str in arrData)\n            {\n                if (Utils.IsNullOrEmpty(str))\n                {\n                    continue;\n                }\n                // If it's sub we just add a sub\n                //maybe sub\n                if (str.StartsWith(Global.httpsProtocol) || str.StartsWith(Global.httpProtocol))\n                {\n                    // Get user subscription info (like donwloaded/uploaded/total usage and expire date)\n                    // Get expire epoch date\n                    var headers = Utils.GetUrlResponseHeader(str,false);\n                    var subInfo = Utils.GetSubscriptionInfoFromHeaders(headers);\n                    //if (subInfo == null)\n                    //{\n                    //    // Handle error\n                    //}\n\n\n                    SubItem subscriptionItem = new SubItem();\n                    subscriptionItem.id = Utils.GetGUID(false);\n                    subscriptionItem.url = str;\n\n                    var LowestPingItem = new ProfileItem()\n                    {\n                        configType = EConfigType.LowestPing,\n                        remarks = \"Lowest Ping\",\n                        address = \"All\",\n                        coreType = ECoreType.Xray,\n                        subid = subscriptionItem.id\n                    };\n                    AddServerCommon(ref config, LowestPingItem, false);\n                    var loadBalanceItem = new ProfileItem()\n                    {\n                        configType = EConfigType.LoadBalance,\n                        remarks = \"Load Balance\",\n                        address = \"All\",\n                        coreType = ECoreType.Xray,\n                        subid = subscriptionItem.id\n                    };\n                    AddServerCommon(ref config, loadBalanceItem, false);\n\n\n                    var subName = Utils.ExtractNameParameterFromUri(str);\n                    int lastSsdortNumber = LazyConfig.Instance.GetLastSubItemSortNumber();\n\n                    if (subName == null)\n                    {\n                        int lastSortNumber = LazyConfig.Instance.GetLastSubItemSortNumber();\n                        subscriptionItem.remarks = $\"Subscription {lastSortNumber + 1}\";\n                    }\n                    else\n                    {\n                        subscriptionItem.remarks = subName;\n                    }\n\n                    if (subInfo != null)\n                    {\n                        subscriptionItem.upload = subInfo.Upload;\n                        subscriptionItem.download = subInfo.Download;\n                        subscriptionItem.total = subInfo.Total;\n                        subscriptionItem.expireDate = subInfo.ExpireDate;\n                        subscriptionItem.remaningExpireDays = subscriptionItem.DaysLeftToExpire();\n                        subscriptionItem.UsedDataGB = subscriptionItem.UsedDataGigaBytes();\n                        subscriptionItem.TotalDataGB = subscriptionItem.TotalDataGigaBytes();\n                        subscriptionItem.profileWebPageUrl = subInfo.ProfileWebPageUrl;\n                    }\n                    \n                    if (subscriptionItem.remarks != null)\n                    {\n                        if (AddSubItem(ref config, subscriptionItem) == 0)\n                        {\n                            countServers++;\n                        }\n                    }\n                    addedSubIds.Add(subscriptionItem.id);\n                    continue;\n                }\n\n\n                // It's server, So we collect all servers and create a new sub and we'll make the servers the subscription member\n                ProfileItem profileItem = ShareHandler.ImportFromClipboardConfig(str, out string msg);\n                if (profileItem == null)\n                {\n                    continue;\n                }\n\n                //exist sub items\n                if (isSub && !Utils.IsNullOrEmpty(subid))\n                {\n                    var existItem = lstOriSub?.FirstOrDefault(t => t.isSub == isSub && CompareProfileItem(t, profileItem, true));\n                    if (existItem != null)\n                    {\n                        profileItem.indexId = existItem.indexId;\n                    }\n                    //filter\n                    if (!Utils.IsNullOrEmpty(subFilter))\n                    {\n                        if (!Regex.IsMatch(profileItem.remarks, subFilter))\n                        {\n                            continue;\n                        }\n                    }\n                }\n                profileItem.subid = subid;\n                profileItem.isSub = isSub;\n\n                servers.Add(profileItem);\n            }\n\n            if (servers.Count < 1)\n            {\n                return (0,addedSubIds);\n            }\n\n            // We create a sub and add the servers to it\n            SubItem subItem = new SubItem();\n            subItem.id = Utils.GetGUID(false);\n            subItem.remarks = $\"Profile {subItem.sort}\";\n\n            // Add sub\n            if (AddSubItem(ref config, subItem) != 0)\n            {\n                // Handle error\n            }\n\n            // Add servers to the sub\n            int addStatus = -1;\n            foreach (ProfileItem item in servers)\n            {\n                item.subid = subItem.id;\n\n                if (item.configType == EConfigType.VMess)\n                {\n                    addStatus = AddServer(ref config, item, false);\n                }\n                else if (item.configType == EConfigType.Shadowsocks)\n                {\n                    addStatus = AddShadowsocksServer(ref config, item, false);\n                }\n                else if (item.configType == EConfigType.Socks)\n                {\n                    addStatus = AddSocksServer(ref config, item, false);\n                }\n                else if (item.configType == EConfigType.Trojan)\n                {\n                    addStatus = AddTrojanServer(ref config, item, false);\n                }\n                else if (item.configType == EConfigType.VLESS)\n                {\n                    addStatus = AddVlessServer(ref config, item, false);\n                }\n                if (addStatus == 0)\n                {\n                    countServers++;\n                }\n            }\n\n            if (countServers != 0)\n            {\n                // lstAdd.Add(usageItem);\n                var LowestPingItem = new ProfileItem()\n                {\n                    configType = EConfigType.LowestPing,\n                    remarks = \"Lowest Ping\",\n                    address = \"All\",\n                    coreType = ECoreType.Xray,\n                    subid = subItem.id,\n                    indexId = \"0\" + new Random().Next(0, 10000000)\n                };\n                AddServerCommon(ref config, LowestPingItem, false);\n                countServers++;\n                var loadBalanceItem = new ProfileItem()\n                {\n                    configType = EConfigType.LoadBalance,\n                    remarks = \"Load Balance\",\n                    address = \"All\",\n                    coreType = ECoreType.Xray,\n                    subid = subItem.id,\n                    indexId = \"1\" + new Random().Next(0, 10000000)\n                };\n                AddServerCommon(ref config, loadBalanceItem, false);\n                countServers++;\n                servers.Add(LowestPingItem);\n                servers.Add(loadBalanceItem);\n            }\n            if (servers.Count > 0)\n            {\n                SqliteHelper.Instance.InsertAll(servers);\n            }\n\n            ToJsonFile(config);\n            return (countServers,addedSubIds);\n        }\n\n        private static int AddBatchServers4Custom(ref Config config, string clipboardData, string subid, bool isSub, List<ProfileItem> lstOriSub)\n        {\n            if (Utils.IsNullOrEmpty(clipboardData))\n            {\n                return -1;\n            }\n\n            //判断str是否包含s的任意一个字符串\n            static bool Containss(string str, params string[] s)\n            {\n                foreach (var item in s)\n                {\n                    if (str.Contains(item, StringComparison.OrdinalIgnoreCase)) return true;\n                }\n                return false;\n            }\n\n            ProfileItem profileItem = new();\n            //Is v2ray configuration\n            V2rayConfig? v2rayConfig = Utils.FromJson<V2rayConfig>(clipboardData);\n            if (v2rayConfig?.inbounds?.Count > 0\n                && v2rayConfig.outbounds?.Count > 0)\n            {\n                var fileName = Utils.GetTempPath($\"{Utils.GetGUID(false)}.json\");\n                File.WriteAllText(fileName, clipboardData);\n\n                profileItem.coreType = ECoreType.Xray;\n                profileItem.address = fileName;\n                profileItem.remarks = \"v2ray_custom\";\n            }\n            //Is Clash configuration\n            else if (Containss(clipboardData, \"port\", \"socks-port\", \"proxies\"))\n            {\n                var fileName = Utils.GetTempPath($\"{Utils.GetGUID(false)}.yaml\");\n                File.WriteAllText(fileName, clipboardData);\n\n                profileItem.coreType = ECoreType.clash;\n                profileItem.address = fileName;\n                profileItem.remarks = \"clash_custom\";\n            }\n            //Is hysteria configuration\n            else if (Containss(clipboardData, \"server\", \"up\", \"down\", \"listen\", \"<html>\", \"<body>\"))\n            {\n                var fileName = Utils.GetTempPath($\"{Utils.GetGUID(false)}.json\");\n                File.WriteAllText(fileName, clipboardData);\n\n                profileItem.coreType = ECoreType.hysteria;\n                profileItem.address = fileName;\n                profileItem.remarks = \"hysteria_custom\";\n            }\n            //Is naiveproxy configuration\n            else if (Containss(clipboardData, \"listen\", \"proxy\", \"<html>\", \"<body>\"))\n            {\n                var fileName = Utils.GetTempPath($\"{Utils.GetGUID(false)}.json\");\n                File.WriteAllText(fileName, clipboardData);\n\n                profileItem.coreType = ECoreType.naiveproxy;\n                profileItem.address = fileName;\n                profileItem.remarks = \"naiveproxy_custom\";\n            }\n            //Is Other configuration\n            else\n            {\n                return -1;\n                //var fileName = Utils.GetTempPath($\"{Utils.GetGUID(false)}.txt\");\n                //File.WriteAllText(fileName, clipboardData);\n\n                //profileItem.address = fileName;\n                //profileItem.remarks = \"other_custom\";\n            }\n\n            if (isSub && !Utils.IsNullOrEmpty(subid))\n            {\n                RemoveServerViaSubid(ref config, subid, isSub);\n            }\n            if (isSub && lstOriSub?.Count == 1)\n            {\n                profileItem.indexId = lstOriSub[0].indexId;\n            }\n            profileItem.subid = subid;\n            profileItem.isSub = isSub;\n\n            if (Utils.IsNullOrEmpty(profileItem.address))\n            {\n                return -1;\n            }\n\n            if (AddCustomServer(ref config, profileItem, true) == 0)\n            {\n                return 1;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        private static int AddBatchServers4SsSIP008(ref Config config, string clipboardData, string subid, bool isSub, List<ProfileItem> lstOriSub)\n        {\n            if (Utils.IsNullOrEmpty(clipboardData))\n            {\n                return -1;\n            }\n\n            if (isSub && !Utils.IsNullOrEmpty(subid))\n            {\n                RemoveServerViaSubid(ref config, subid, isSub);\n            }\n\n            //SsSIP008\n            var lstSsServer = Utils.FromJson<List<SsServer>>(clipboardData);\n            if (lstSsServer?.Count <= 0)\n            {\n                var ssSIP008 = Utils.FromJson<SsSIP008>(clipboardData);\n                if (ssSIP008?.servers?.Count > 0)\n                {\n                    lstSsServer = ssSIP008.servers;\n                }\n            }\n\n            if (lstSsServer?.Count > 0)\n            {\n                int counter = 0;\n                foreach (var it in lstSsServer)\n                {\n                    var ssItem = new ProfileItem()\n                    {\n                        subid = subid,\n                        remarks = it.remarks,\n                        security = it.method,\n                        id = it.password,\n                        address = it.server,\n                        port = Utils.ToInt(it.server_port)\n                    };\n                    ssItem.subid = subid;\n                    ssItem.isSub = isSub;\n                    if (AddShadowsocksServer(ref config, ssItem) == 0)\n                    {\n                        counter++;\n                    }\n                }\n                ToJsonFile(config);\n                return counter;\n            }\n\n            return -1;\n        }\n\n        public static int AddBatchServers(ref Config config, string clipboardData, string subid, bool isSub)\n        {\n            List<ProfileItem>? lstOriSub = null;\n            if (isSub && !Utils.IsNullOrEmpty(subid))\n            {\n                lstOriSub = LazyConfig.Instance.ProfileItems(subid);\n            }\n\n            var counter = 0;\n            if (Utils.IsBase64String(clipboardData))\n            {\n                counter = AddBatchServers(ref config, Utils.Base64Decode(clipboardData), subid, isSub, lstOriSub);\n            }\n            if (counter < 1)\n            {\n                counter = AddBatchServers(ref config, clipboardData, subid, isSub, lstOriSub);\n            }\n            if (counter < 1)\n            {\n                counter = AddBatchServers(ref config, Utils.Base64Decode(clipboardData), subid, isSub, lstOriSub);\n            }\n\n            if (counter < 1)\n            {\n                counter = AddBatchServers4SsSIP008(ref config, clipboardData, subid, isSub, lstOriSub);\n            }\n\n            //maybe other sub\n            if (counter < 1)\n            {\n                counter = AddBatchServers4Custom(ref config, clipboardData, subid, isSub, lstOriSub);\n            }\n\n            return counter;\n        }\n\n        #endregion Batch add servers\n\n        #region Sub & Group\n\n        /// <summary>\n        /// add sub\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"url\"></param>\n        /// <returns></returns>\n        public static int AddSubItem(ref Config config, string url, string? subName, SubscriptionInfo? subInfo)\n        {\n            //already exists\n            if (SqliteHelper.Instance.Table<SubItem>().Where(e => e.url == url).Count() > 0)\n            {\n                return 0;\n            }\n\n            if (subName == null)\n            {\n                subName = \"Imported Sub\";\n            }\n            SubItem subItem = new()\n            {\n                id = string.Empty,\n                remarks = subName,\n                url = url\n            };\n\n            if (subInfo != null)\n            {\n                subItem.upload = subInfo.Upload;\n                subItem.download = subInfo.Download;\n                subItem.total = subInfo.Total;\n                subItem.expireDate = subInfo.ExpireDate;\n                subItem.profileWebPageUrl = subInfo.ProfileWebPageUrl;\n            }\n\n            return AddSubItem(ref config, subItem);\n        }\n\n        public static int AddSubItem(ref Config config, SubItem subItem,bool doNotFocusOnWindowAfterAdd = false)\n        {\n            if (Utils.IsNullOrEmpty(subItem.id))\n            {\n                subItem.id = Utils.GetGUID(false);\n\n                if (subItem.sort <= 0)\n                {\n                    var maxSort = 0;\n                    if (SqliteHelper.Instance.Table<SubItem>().Count() > 0)\n                    {\n                        maxSort = SqliteHelper.Instance.Table<SubItem>().Max(t => t == null ? 0 : t.sort);\n                    }\n                    subItem.sort = maxSort + 1;\n                }\n            }\n            if (subItem.sort <= 0)\n            {\n                var maxSort = 0;\n                if (SqliteHelper.Instance.Table<SubItem>().Count() > 0)\n                {\n                    maxSort = SqliteHelper.Instance.Table<SubItem>().Max(t => t == null ? 0 : t.sort);\n                }\n                subItem.sort = maxSort + 1;\n            }\n            var subs = LazyConfig.Instance.SubItems();\n            // Do not add the sub if it's already exist\n            foreach (SubItem item in subs)\n            {\n                if (subItem.url == item.url)\n                    return 0;\n            }\n\n            if (SqliteHelper.Instance.Replace(subItem) > 0)\n            {\n                if (!doNotFocusOnWindowAfterAdd)\n                    Utils.SetMainPageReload();\n                return 0;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        /// <summary>\n        /// 移除服务器\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"subid\"></param>\n        /// <returns></returns>\n        public static int RemoveServerViaSubid(ref Config config, string subid, bool isSub)\n        {\n            if (Utils.IsNullOrEmpty(subid))\n            {\n                return -1;\n            }\n            var customProfile = SqliteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid && t.configType == EConfigType.Custom).ToList();\n            if (isSub)\n            {\n                SqliteHelper.Instance.Execute($\"delete from ProfileItem where isSub = 1 and subid = '{subid}'\");\n            }\n            else\n            {\n                SqliteHelper.Instance.Execute($\"delete from ProfileItem where subid = '{subid}'\");\n            }\n            foreach (var item in customProfile)\n            {\n                File.Delete(Utils.GetConfigPath(item.address));\n            }\n\n            return 0;\n        }\n\n        public static int DeleteSubItem(ref Config config, string id)\n        {\n            var item = LazyConfig.Instance.GetSubItem(id);\n            if (item is null)\n            {\n                return 0;\n            }\n            SqliteHelper.Instance.Delete(item);\n            RemoveServerViaSubid(ref config, id, false);\n\n            return 0;\n        }\n\n        public static int MoveToGroup(Config config, List<ProfileItem> lstProfile, string subid)\n        {\n            foreach (var item in lstProfile)\n            {\n                item.subid = subid;\n            }\n            SqliteHelper.Instance.UpdateAll(lstProfile);\n\n            return 0;\n        }\n\n        #endregion Sub & Group\n\n        #region Routing\n\n        public static int SaveRoutingItem(ref Config config, RoutingItem item)\n        {\n            if (Utils.IsNullOrEmpty(item.id))\n            {\n                item.id = Utils.GetGUID(false);\n            }\n\n            if (SqliteHelper.Instance.Replace(item) > 0)\n            {\n                return 0;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        /// <summary>\n        /// AddBatchRoutingRules\n        /// </summary>\n        /// <param name=\"config\"></param>\n        /// <param name=\"clipboardData\"></param>\n        /// <returns></returns>\n        public static int AddBatchRoutingRules(ref RoutingItem routingItem, string clipboardData)\n        {\n            if (Utils.IsNullOrEmpty(clipboardData))\n            {\n                return -1;\n            }\n\n            var lstRules = Utils.FromJson<List<RulesItem>>(clipboardData);\n            if (lstRules == null)\n            {\n                return -1;\n            }\n\n            foreach (var item in lstRules)\n            {\n                item.id = Utils.GetGUID(false);\n            }\n            routingItem.ruleNum = lstRules.Count;\n            routingItem.ruleSet = Utils.ToJson(lstRules, false);\n\n            if (Utils.IsNullOrEmpty(routingItem.id))\n            {\n                routingItem.id = Utils.GetGUID(false);\n            }\n\n            if (SqliteHelper.Instance.Replace(routingItem) > 0)\n            {\n                return 0;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        /// <summary>\n        /// MoveRoutingRule\n        /// </summary>\n        /// <param name=\"routingItem\"></param>\n        /// <param name=\"index\"></param>\n        /// <param name=\"eMove\"></param>\n        /// <returns></returns>\n        public static int MoveRoutingRule(List<RulesItem> rules, int index, EMove eMove, int pos = -1)\n        {\n            int count = rules.Count;\n            if (index < 0 || index > rules.Count - 1)\n            {\n                return -1;\n            }\n            switch (eMove)\n            {\n                case EMove.Top:\n                    {\n                        if (index == 0)\n                        {\n                            return 0;\n                        }\n                        var item = Utils.DeepCopy(rules[index]);\n                        rules.RemoveAt(index);\n                        rules.Insert(0, item);\n\n                        break;\n                    }\n                case EMove.Up:\n                    {\n                        if (index == 0)\n                        {\n                            return 0;\n                        }\n                        var item = Utils.DeepCopy(rules[index]);\n                        rules.RemoveAt(index);\n                        rules.Insert(index - 1, item);\n\n                        break;\n                    }\n\n                case EMove.Down:\n                    {\n                        if (index == count - 1)\n                        {\n                            return 0;\n                        }\n                        var item = Utils.DeepCopy(rules[index]);\n                        rules.RemoveAt(index);\n                        rules.Insert(index + 1, item);\n\n                        break;\n                    }\n                case EMove.Bottom:\n                    {\n                        if (index == count - 1)\n                        {\n                            return 0;\n                        }\n                        var item = Utils.DeepCopy(rules[index]);\n                        rules.RemoveAt(index);\n                        rules.Add(item);\n\n                        break;\n                    }\n                case EMove.Position:\n                    {\n                        var removeItem = rules[index];\n                        var item = Utils.DeepCopy(rules[index]);\n                        rules.Insert(pos, item);\n                        rules.Remove(removeItem);\n                        break;\n                    }\n            }\n            return 0;\n        }\n\n        public static int SetDefaultRouting(ref Config config, RoutingItem routingItem)\n        {\n            if (SqliteHelper.Instance.Table<RoutingItem>().Where(t => t.id == routingItem.id).Count() > 0)\n            {\n                config.routingBasicItem.routingIndexId = routingItem.id;\n            }\n\n            ToJsonFile(config);\n\n            return 0;\n        }\n\n        public static RoutingItem GetDefaultRouting(ref Config config)\n        {\n            var item = LazyConfig.Instance.GetRoutingItem(config.routingBasicItem.routingIndexId);\n            if (item is null)\n            {\n                var item2 = SqliteHelper.Instance.Table<RoutingItem>().FirstOrDefault(t => t.locked == false);\n                SetDefaultRouting(ref config, item2);\n                return item2;\n            }\n\n            return item;\n        }\n\n        public static int InitBuiltinRouting(ref Config config, bool blImportAdvancedRules = false)\n        {\n            var items = LazyConfig.Instance.RoutingItems();\n            if (blImportAdvancedRules || items.Count <= 0)\n            {\n                var maxSort = items.Count;\n                //Bypass the mainland\n                var item2 = new RoutingItem()\n                {\n                    remarks = \"All Foreign Sites سایتهای خارجی\",\n                    url = string.Empty,\n                    sort = maxSort + 1,\n                };\n                AddBatchRoutingRules(ref item2, Utils.GetEmbedText(Global.CustomRoutingFileName + \"white\"));\n\n                //Blacklist\n                var item3 = new RoutingItem()\n                {\n                    remarks = \"Only blocked sites فقط سایت های فیلتر\",\n                    url = string.Empty,\n                    sort = maxSort + 2,\n                };\n                AddBatchRoutingRules(ref item3, Utils.GetEmbedText(Global.CustomRoutingFileName + \"black\"));\n\n                //Global\n                var item1 = new RoutingItem()\n                {\n                    remarks = \"Global\",\n                    url = string.Empty,\n                    sort = maxSort + 3,\n                };\n                AddBatchRoutingRules(ref item1, Utils.GetEmbedText(Global.CustomRoutingFileName + \"global\"));\n\n                if (!blImportAdvancedRules)\n                {\n                    SetDefaultRouting(ref config, item2);\n                }\n            }\n\n            if (GetLockedRoutingItem(ref config) == null)\n            {\n                var item1 = new RoutingItem()\n                {\n                    remarks = \"locked\",\n                    url = string.Empty,\n                    locked = true,\n                };\n                AddBatchRoutingRules(ref item1, Utils.GetEmbedText(Global.CustomRoutingFileName + \"locked\"));\n            }\n            return 0;\n        }\n\n        public static RoutingItem GetLockedRoutingItem(ref Config config)\n        {\n            return SqliteHelper.Instance.Table<RoutingItem>().FirstOrDefault(it => it.locked == true);\n        }\n\n        public static void RemoveRoutingItem(RoutingItem routingItem)\n        {\n            SqliteHelper.Instance.Delete(routingItem);\n        }\n\n        #endregion Routing\n\n        #region DNS\n\n        public static int InitBuiltinDNS(Config config)\n        {\n            var items = LazyConfig.Instance.DNSItems();\n            if (items.Count <= 0)\n            {\n                var item = new DNSItem()\n                {\n                    remarks = \"V2ray\",\n                    coreType = ECoreType.Xray,\n                };\n                SaveDNSItems(config, item);\n\n                var item2 = new DNSItem()\n                {\n                    remarks = \"sing-box\",\n                    coreType = ECoreType.sing_box,\n                };\n                SaveDNSItems(config, item2);\n            }\n\n            return 0;\n        }\n\n        public static int SaveDNSItems(Config config, DNSItem item)\n        {\n            if (Utils.IsNullOrEmpty(item.id))\n            {\n                item.id = Utils.GetGUID(false);\n            }\n\n            if (SqliteHelper.Instance.Replace(item) > 0)\n            {\n                return 0;\n            }\n            else\n            {\n                return -1;\n            }\n        }\n\n        #endregion DNS\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/CoreConfigHandler.cs",
    "content": "﻿using System.IO;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    /// <summary>\n    /// Core configuration file processing class\n    /// </summary>\n    internal class CoreConfigHandler\n    {\n        public static int GenerateClientConfig(ProfileItem node, string? fileName, out string msg, out string content)\n        {\n            content = string.Empty;\n            try\n            {\n                if (node == null)\n                {\n                    msg = ResUI.CheckServerSettings;\n                    return -1;\n                }\n\n                msg = ResUI.InitialConfiguration;\n                if (node.configType == EConfigType.Custom)\n                {\n                    return GenerateClientCustomConfig(node, fileName, out msg);\n                }\n                /*hiddify{*/\n                else if (node.configType == EConfigType.LowestPing || node.configType == EConfigType.LoadBalance)\n                {\n\n                    var coreConfigV2ray = new CoreConfigV2ray(LazyConfig.Instance.GetConfig());\n                    if (coreConfigV2ray.HiddifyGenerateSubConfigContent(node, out V2rayConfig? v2rayConfig, out msg) != 0)\n                    {\n                        return -1;\n                    }\n                    if (Utils.IsNullOrEmpty(fileName))\n                    {\n                        content = Utils.ToJson(v2rayConfig);\n                    }\n                    else\n                    {\n                        Utils.ToJsonFile(v2rayConfig, fileName, false);\n                    }\n                }\n                /*hiddify}*/\n                else if (LazyConfig.Instance.GetCoreType(node, node.configType) == ECoreType.sing_box)\n                {\n                    var configGenSingbox = new CoreConfigSingbox(LazyConfig.Instance.GetConfig());\n                    if (configGenSingbox.GenerateClientConfigContent(node, out SingboxConfig? singboxConfig, out msg) != 0)\n                    {\n                        return -1;\n                    }\n                    if (Utils.IsNullOrEmpty(fileName))\n                    {\n                        content = Utils.ToJson(singboxConfig);\n                    }\n                    else\n                    {\n                        Utils.ToJsonFile(singboxConfig, fileName, false);\n                    }\n                }\n                else\n                {\n                    var coreConfigV2ray = new CoreConfigV2ray(LazyConfig.Instance.GetConfig());\n                    if (coreConfigV2ray.GenerateClientConfigContent(node, out V2rayConfig? v2rayConfig, out msg) != 0)\n                    {\n                        return -1;\n                    }\n                    if (Utils.IsNullOrEmpty(fileName))\n                    {\n                        content = Utils.ToJson(v2rayConfig);\n                    }\n                    else\n                    {\n                        Utils.ToJsonFile(v2rayConfig, fileName, false);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(\"GenerateClientConfig\", ex);\n                msg = ResUI.FailedGenDefaultConfiguration;\n                return -1;\n            }\n            return 0;\n        }\n\n        private static int GenerateClientCustomConfig(ProfileItem node, string? fileName, out string msg)\n        {\n            try\n            {\n                if (node == null || fileName is null)\n                {\n                    msg = ResUI.CheckServerSettings;\n                    return -1;\n                }\n\n                if (File.Exists(fileName))\n                {\n                    File.Delete(fileName);\n                }\n\n                string addressFileName = node.address;\n                if (!File.Exists(addressFileName))\n                {\n                    addressFileName = Utils.GetConfigPath(addressFileName);\n                }\n                if (!File.Exists(addressFileName))\n                {\n                    msg = ResUI.FailedGenDefaultConfiguration;\n                    return -1;\n                }\n                File.Copy(addressFileName, fileName);\n\n                //check again\n                if (!File.Exists(fileName))\n                {\n                    msg = ResUI.FailedGenDefaultConfiguration;\n                    return -1;\n                }\n\n                //overwrite port\n                if (node.preSocksPort <= 0)\n                {\n                    var fileContent = File.ReadAllLines(fileName).ToList();\n                    var coreType = LazyConfig.Instance.GetCoreType(node, node.configType);\n                    switch (coreType)\n                    {\n                        case ECoreType.v2fly:\n                        case ECoreType.SagerNet:\n                        case ECoreType.Xray:\n                        case ECoreType.v2fly_v5:\n                            break;\n\n                        case ECoreType.clash:\n                        case ECoreType.clash_meta:\n                            //remove the original\n                            var indexPort = fileContent.FindIndex(t => t.Contains(\"port:\"));\n                            if (indexPort >= 0)\n                            {\n                                fileContent.RemoveAt(indexPort);\n                            }\n                            indexPort = fileContent.FindIndex(t => t.Contains(\"socks-port:\"));\n                            if (indexPort >= 0)\n                            {\n                                fileContent.RemoveAt(indexPort);\n                            }\n\n                            fileContent.Add($\"port: {LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}\");\n                            fileContent.Add($\"socks-port: {LazyConfig.Instance.GetLocalPort(Global.InboundSocks)}\");\n                            break;\n                    }\n                    File.WriteAllLines(fileName, fileContent);\n                }\n\n                msg = string.Format(ResUI.SuccessfulConfiguration, \"\");\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(\"GenerateClientCustomConfig\", ex);\n                msg = ResUI.FailedGenDefaultConfiguration;\n                return -1;\n            }\n            return 0;\n        }\n\n        public static string GenerateClientSpeedtestConfigString(Config config, List<ServerTestItem> selecteds, out string msg)\n        {\n            var coreConfigV2ray = new CoreConfigV2ray(config);\n            return coreConfigV2ray.GenerateClientSpeedtestConfigString(selecteds, out msg);\n        }\n\n\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/CoreConfigSingbox.cs",
    "content": "﻿using v2rayN.Base;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    internal class CoreConfigSingbox\n    {\n        private string SampleClient = Global.SingboxSampleClient;\n        private Config _config;\n\n        public CoreConfigSingbox(Config config)\n        {\n            _config = config;\n        }\n\n        public int GenerateClientConfigContent(ProfileItem node, out SingboxConfig? singboxConfig, out string msg)\n        {\n            singboxConfig = null;\n            try\n            {\n                if (node == null\n                    || node.port <= 0)\n                {\n                    msg = ResUI.CheckServerSettings;\n                    return -1;\n                }\n\n                msg = ResUI.InitialConfiguration;\n\n                string result = Utils.GetEmbedText(SampleClient);\n                if (Utils.IsNullOrEmpty(result))\n                {\n                    msg = ResUI.FailedGetDefaultConfiguration;\n                    return -1;\n                }\n\n                singboxConfig = Utils.FromJson<SingboxConfig>(result);\n                if (singboxConfig == null)\n                {\n                    msg = ResUI.FailedGenDefaultConfiguration;\n                    return -1;\n                }\n\n                log(singboxConfig);\n\n                inbound(singboxConfig);\n\n                outbound(node, singboxConfig);\n\n                routing(singboxConfig);\n\n                dns(node, singboxConfig);\n\n                //statistic(singboxConfig);\n\n                msg = string.Format(ResUI.SuccessfulConfiguration, \"\");\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(\"GenerateClientConfig4Singbox\", ex);\n                msg = ResUI.FailedGenDefaultConfiguration;\n                return -1;\n            }\n            return 0;\n        }\n\n        private int log(SingboxConfig singboxConfig)\n        {\n            try\n            {\n                switch (_config.coreBasicItem.loglevel)\n                {\n                    case \"debug\":\n                    case \"info\":\n                    case \"error\":\n                        singboxConfig.log.level = _config.coreBasicItem.loglevel;\n                        break;\n\n                    case \"warning\":\n                        singboxConfig.log.level = \"warn\";\n                        break;\n\n                    default:\n                        break;\n                }\n                if (_config.coreBasicItem.loglevel == \"none\")\n                {\n                    singboxConfig.log.disabled = true;\n                }\n                if (_config.coreBasicItem.logEnabled)\n                {\n                    var dtNow = DateTime.Now;\n                    singboxConfig.log.output = Utils.GetLogPath($\"sbox_{dtNow:yyyy-MM-dd}.txt\");\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        #region inbound private\n\n        private int inbound(SingboxConfig singboxConfig)\n        {\n            try\n            {\n                if (_config.tunModeItem.enableTun)\n                {\n                    singboxConfig.inbounds.Clear();\n\n                    if (_config.tunModeItem.mtu <= 0)\n                    {\n                        _config.tunModeItem.mtu = Convert.ToInt32(Global.TunMtus[0]);\n                    }\n                    if (Utils.IsNullOrEmpty(_config.tunModeItem.stack))\n                    {\n                        _config.tunModeItem.stack = Global.TunStacks[0];\n                    }\n\n                    var tunInbound = Utils.FromJson<Inbound4Sbox>(Utils.GetEmbedText(Global.TunSingboxInboundFileName));\n                    tunInbound.mtu = _config.tunModeItem.mtu;\n                    tunInbound.strict_route = _config.tunModeItem.strictRoute;\n                    tunInbound.stack = _config.tunModeItem.stack;\n\n                    singboxConfig.inbounds.Add(tunInbound);\n                }\n                else\n                {\n                    var inbound = singboxConfig.inbounds[0];\n                    inbound.listen_port = LazyConfig.Instance.GetLocalPort(Global.InboundSocks);\n                    inbound.sniff = _config.inbound[0].sniffingEnabled;\n                    inbound.sniff_override_destination = _config.inbound[0].routeOnly ? false : _config.inbound[0].sniffingEnabled;\n                    inbound.domain_strategy = Utils.IsNullOrEmpty(_config.routingBasicItem.domainStrategy4Singbox) ? null : _config.routingBasicItem.domainStrategy4Singbox;\n\n                    if (_config.routingBasicItem.enableRoutingAdvanced)\n                    {\n                        var routing = ConfigHandler.GetDefaultRouting(ref _config);\n                        if (!Utils.IsNullOrEmpty(routing.domainStrategy4Singbox))\n                        {\n                            inbound.domain_strategy = routing.domainStrategy4Singbox;\n                        }\n                    }\n\n                    //http\n                    var inbound2 = GetInbound(inbound, Global.InboundHttp, 1, false);\n                    singboxConfig.inbounds.Add(inbound2);\n\n                    if (_config.inbound[0].allowLANConn)\n                    {\n                        if (_config.inbound[0].newPort4LAN)\n                        {\n                            var inbound3 = GetInbound(inbound, Global.InboundSocks2, 2, true);\n                            inbound3.listen = \"::\";\n                            singboxConfig.inbounds.Add(inbound3);\n\n                            var inbound4 = GetInbound(inbound, Global.InboundHttp2, 3, false);\n                            inbound4.listen = \"::\";\n                            singboxConfig.inbounds.Add(inbound4);\n\n                            //auth\n                            if (!Utils.IsNullOrEmpty(_config.inbound[0].user) && !Utils.IsNullOrEmpty(_config.inbound[0].pass))\n                            {\n                                inbound3.users = new() { new() { username = _config.inbound[0].user, password = _config.inbound[0].pass } };\n                                inbound4.users = new() { new() { username = _config.inbound[0].user, password = _config.inbound[0].pass } };\n                            }\n                        }\n                        else\n                        {\n                            inbound.listen = \"::\";\n                            inbound2.listen = \"::\";\n                        }\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private Inbound4Sbox? GetInbound(Inbound4Sbox inItem, string tag, int offset, bool bSocks)\n        {\n            var inbound = Utils.DeepCopy(inItem);\n            inbound.tag = tag;\n            inbound.listen_port = inItem.listen_port + offset;\n            inbound.type = bSocks ? Global.InboundSocks : Global.InboundHttp;\n            return inbound;\n        }\n\n        #endregion inbound private\n\n        #region outbound private\n\n        private int outbound(ProfileItem node, SingboxConfig singboxConfig)\n        {\n            try\n            {\n                if (_config.tunModeItem.enableTun)\n                {\n                    singboxConfig.outbounds.Add(new()\n                    {\n                        type = \"dns\",\n                        tag = \"dns_out\"\n                    });\n                }\n\n                var outbound = singboxConfig.outbounds[0];\n                outbound.server = node.address;\n                outbound.server_port = node.port;\n\n                if (node.configType == EConfigType.VMess)\n                {\n                    outbound.type = Global.vmessProtocolLite;\n\n                    outbound.uuid = node.id;\n                    outbound.alter_id = node.alterId;\n                    if (Global.vmessSecuritys.Contains(node.security))\n                    {\n                        outbound.security = node.security;\n                    }\n                    else\n                    {\n                        outbound.security = Global.DefaultSecurity;\n                    }\n\n                    outboundMux(node, outbound);\n                }\n                else if (node.configType == EConfigType.Shadowsocks)\n                {\n                    outbound.type = Global.ssProtocolLite;\n\n                    outbound.method = LazyConfig.Instance.GetShadowsocksSecuritys(node).Contains(node.security) ? node.security : \"none\";\n                    outbound.password = node.id;\n\n                    outboundMux(node, outbound);\n                }\n                else if (node.configType == EConfigType.Socks)\n                {\n                    outbound.type = Global.socksProtocolLite;\n\n                    outbound.version = \"5\";\n                    if (!Utils.IsNullOrEmpty(node.security)\n                      && !Utils.IsNullOrEmpty(node.id))\n                    {\n                        outbound.username = node.security;\n                        outbound.password = node.id;\n                    }\n                }\n                else if (node.configType == EConfigType.VLESS)\n                {\n                    outbound.type = Global.vlessProtocolLite;\n\n                    outbound.uuid = node.id;\n                    outbound.flow = node.flow;\n\n                    outbound.packet_encoding = \"xudp\";\n                }\n                else if (node.configType == EConfigType.Trojan)\n                {\n                    outbound.type = Global.trojanProtocolLite;\n\n                    outbound.password = node.id;\n\n                    outboundMux(node, outbound);\n                }\n\n                outboundTls(node, outbound);\n\n                outboundTransport(node, outbound);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int outboundMux(ProfileItem node, Outbound4Sbox outbound)\n        {\n            try\n            {\n                if (_config.coreBasicItem.muxEnabled)\n                {\n                    var mux = new Multiplex4Sbox()\n                    {\n                        enabled = true,\n                        protocol = \"smux\",\n                        max_connections = 4,\n                        min_streams = 4,\n                        max_streams = 0,\n                    };\n                    outbound.multiplex = mux;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int outboundTls(ProfileItem node, Outbound4Sbox outbound)\n        {\n            try\n            {\n                if (node.streamSecurity == Global.StreamSecurityReality || node.streamSecurity == Global.StreamSecurity)\n                {\n                    var tls = new Tls4Sbox()\n                    {\n                        enabled = true,\n                        server_name = node.sni,\n                        insecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? _config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),\n                        alpn = node.GetAlpn(),\n                    };\n                    if (!Utils.IsNullOrEmpty(node.fingerprint))\n                    {\n                        tls.utls = new Utls4Sbox()\n                        {\n                            enabled = true,\n                            fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.coreBasicItem.defFingerprint : node.fingerprint\n                        };\n                    }\n                    if (node.streamSecurity == Global.StreamSecurityReality)\n                    {\n                        tls.reality = new Reality4Sbox()\n                        {\n                            enabled = true,\n                            public_key = node.publicKey,\n                            short_id = node.shortId\n                        };\n                        tls.insecure = false;\n                    }\n                    outbound.tls = tls;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int outboundTransport(ProfileItem node, Outbound4Sbox outbound)\n        {\n            try\n            {\n                var transport = new Transport4Sbox();\n\n                switch (node.GetNetwork())\n                {\n                    case \"h2\":\n                        transport.type = \"http\";\n                        transport.host = Utils.IsNullOrEmpty(node.requestHost) ? null : Utils.String2List(node.requestHost);\n                        transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path;\n                        break;\n\n                    case \"ws\":\n                        transport.type = \"ws\";\n                        transport.path = Utils.IsNullOrEmpty(node.path) ? null : node.path;\n                        break;\n\n                    case \"quic\":\n                        transport.type = \"quic\";\n                        break;\n\n                    case \"grpc\":\n                        transport.type = \"grpc\";\n                        transport.service_name = node.path;\n                        transport.idle_timeout = _config.grpcItem.idle_timeout.ToString(\"##s\");\n                        transport.ping_timeout = _config.grpcItem.health_check_timeout.ToString(\"##s\");\n                        transport.permit_without_stream = _config.grpcItem.permit_without_stream;\n                        break;\n\n                    default:\n                        transport = null;\n                        break;\n                }\n\n                outbound.transport = transport;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        #endregion outbound private\n\n        #region routing rule private\n\n        private int routing(SingboxConfig singboxConfig)\n        {\n            try\n            {\n                if (_config.tunModeItem.enableTun)\n                {\n                    singboxConfig.route.auto_detect_interface = true;\n\n                    var tunRules = Utils.FromJson<List<Rule4Sbox>>(Utils.GetEmbedText(Global.TunSingboxRulesFileName));\n                    singboxConfig.route.rules.AddRange(tunRules);\n\n                    routingDirectExe(out List<string> lstDnsExe, out List<string> lstDirectExe);\n                    singboxConfig.route.rules.Add(new()\n                    {\n                        port = new() { 53 },\n                        outbound = \"dns_out\",\n                        process_name = lstDnsExe\n                    });\n\n                    singboxConfig.route.rules.Add(new()\n                    {\n                        outbound = \"direct\",\n                        process_name = lstDirectExe\n                    });\n                }\n\n                if (_config.routingBasicItem.enableRoutingAdvanced)\n                {\n                    var routing = ConfigHandler.GetDefaultRouting(ref _config);\n                    if (routing != null)\n                    {\n                        var rules = Utils.FromJson<List<RulesItem>>(routing.ruleSet);\n                        foreach (var item in rules!)\n                        {\n                            if (item.enabled)\n                            {\n                                routingUserRule(item, singboxConfig.route.rules);\n                            }\n                        }\n                    }\n                }\n                else\n                {\n                    var lockedItem = ConfigHandler.GetLockedRoutingItem(ref _config);\n                    if (lockedItem != null)\n                    {\n                        var rules = Utils.FromJson<List<RulesItem>>(lockedItem.ruleSet);\n                        foreach (var item in rules!)\n                        {\n                            routingUserRule(item, singboxConfig.route.rules);\n                        }\n                    }\n                }\n\n                if (_config.tunModeItem.enableTun)\n                {\n                    if (_config.tunModeItem.bypassMode)\n                    {\n                        //direct ips\n                        if (_config.tunModeItem.directIP != null && _config.tunModeItem.directIP.Count > 0)\n                        {\n                            singboxConfig.route.rules.Add(new() { outbound = \"direct\", ip_cidr = _config.tunModeItem.directIP });\n                        }\n                        //direct process\n                        if (_config.tunModeItem.directProcess != null && _config.tunModeItem.directProcess.Count > 0)\n                        {\n                            singboxConfig.route.rules.Add(new() { outbound = \"direct\", process_name = _config.tunModeItem.directProcess });\n                        }\n                    }\n                    else\n                    {\n                        //proxy ips\n                        if (_config.tunModeItem.proxyIP != null && _config.tunModeItem.proxyIP.Count > 0)\n                        {\n                            singboxConfig.route.rules.Add(new() { outbound = \"proxy\", ip_cidr = _config.tunModeItem.proxyIP });\n                        }\n                        //proxy process\n                        if (_config.tunModeItem.proxyProcess != null && _config.tunModeItem.proxyProcess.Count > 0)\n                        {\n                            singboxConfig.route.rules.Add(new() { outbound = \"proxy\", process_name = _config.tunModeItem.proxyProcess });\n                        }\n\n                        singboxConfig.route.rules.Add(new() { outbound = \"direct\", inbound = new() { \"tun-in\" } });\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private void routingDirectExe(out List<string> lstDnsExe, out List<string> lstDirectExe)\n        {\n            lstDnsExe = new();\n            lstDirectExe = new();\n            var coreInfos = LazyConfig.Instance.GetCoreInfos();\n            foreach (var it in coreInfos)\n            {\n                if (it.coreType == ECoreType.v2rayN)\n                {\n                    continue;\n                }\n                foreach (var it2 in it.coreExes)\n                {\n                    if (!lstDnsExe.Contains(it2) && it.coreType != ECoreType.sing_box)\n                    {\n                        lstDnsExe.Add($\"{it2}.exe\");\n                    }\n\n                    if (!lstDirectExe.Contains(it2))\n                    {\n                        lstDirectExe.Add($\"{it2}.exe\");\n                    }\n                }\n            }\n        }\n\n        private int routingUserRule(RulesItem item, List<Rule4Sbox> rules)\n        {\n            try\n            {\n                if (item == null)\n                {\n                    return 0;\n                }\n\n                var rule = new Rule4Sbox()\n                {\n                    outbound = item.outboundTag,\n                };\n\n                if (!Utils.IsNullOrEmpty(item.port))\n                {\n                    if (item.port.Contains(\"-\"))\n                    {\n                        rule.port_range = new List<string> { item.port.Replace(\"-\", \":\") };\n                    }\n                    else\n                    {\n                        rule.port = new List<int> { Utils.ToInt(item.port) };\n                    }\n                }\n                if (item.protocol?.Count > 0)\n                {\n                    rule.protocol = item.protocol;\n                }\n                if (item.inboundTag?.Count >= 0)\n                {\n                    rule.inbound = item.inboundTag;\n                }\n                var rule2 = Utils.DeepCopy(rule);\n\n                var hasDomainIp = false;\n                if (item.domain?.Count > 0)\n                {\n                    foreach (var it in item.domain)\n                    {\n                        parseV2Domain(it, rule);\n                    }\n                    rules.Add(rule);\n                    hasDomainIp = true;\n                }\n\n                if (item.ip?.Count > 0)\n                {\n                    foreach (var it in item.ip)\n                    {\n                        parseV2Address(it, rule2);\n                    }\n                    rules.Add(rule2);\n                    hasDomainIp = true;\n                }\n\n                if (!hasDomainIp)\n                {\n                    rules.Add(rule);\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private void parseV2Domain(string domain, Rule4Sbox rule)\n        {\n            if (domain.StartsWith(\"ext:\") || domain.StartsWith(\"ext-domain:\"))\n            {\n                return;\n            }\n            else if (domain.StartsWith(\"geosite:\"))\n            {\n                if (rule.geosite is null) { rule.geosite = new(); }\n                rule.geosite?.Add(domain.Substring(8));\n            }\n            else if (domain.StartsWith(\"regexp:\"))\n            {\n                if (rule.domain_regex is null) { rule.domain_regex = new(); }\n                rule.domain_regex?.Add(domain.Replace(Global.RoutingRuleComma, \",\").Substring(7));\n            }\n            else if (domain.StartsWith(\"domain:\"))\n            {\n                if (rule.domain is null) { rule.domain = new(); }\n                if (rule.domain_suffix is null) { rule.domain_suffix = new(); }\n                rule.domain?.Add(domain.Substring(7));\n                rule.domain_suffix?.Add(\".\" + domain.Substring(7));\n            }\n            else if (domain.StartsWith(\"full:\"))\n            {\n                if (rule.domain is null) { rule.domain = new(); }\n                rule.domain?.Add(domain.Substring(5));\n            }\n            else if (domain.StartsWith(\"keyword:\"))\n            {\n                if (rule.domain_keyword is null) { rule.domain_keyword = new(); }\n                rule.domain_keyword?.Add(domain.Substring(8));\n            }\n            else\n            {\n                if (rule.domain_keyword is null) { rule.domain_keyword = new(); }\n                rule.domain_keyword?.Add(domain);\n            }\n        }\n\n        private void parseV2Address(string address, Rule4Sbox rule)\n        {\n            if (address.StartsWith(\"ext:\") || address.StartsWith(\"ext-ip:\"))\n            {\n                return;\n            }\n            else if (address.StartsWith(\"geoip:!\"))\n            {\n                return;\n            }\n            else if (address.StartsWith(\"geoip:\"))\n            {\n                if (rule.geoip is null) { rule.geoip = new(); }\n                rule.geoip?.Add(address.Substring(6));\n            }\n            else\n            {\n                if (rule.ip_cidr is null) { rule.ip_cidr = new(); }\n                rule.ip_cidr?.Add(address);\n            }\n        }\n\n        #endregion routing rule private\n\n        #region dns private\n\n        private int dns(ProfileItem node, SingboxConfig singboxConfig)\n        {\n            try\n            {\n                Dns4Sbox? dns4Sbox;\n                if (_config.tunModeItem.enableTun)\n                {\n                    string tunDNS = String.Empty;\n                    if (_config.tunModeItem.bypassMode)\n                    {\n                        tunDNS = _config.tunModeItem.directDNS;\n                    }\n                    else\n                    {\n                        tunDNS = _config.tunModeItem.proxyDNS;\n                    }\n                    if (tunDNS.IsNullOrEmpty() || Utils.FromJson<Dns4Sbox>(tunDNS) is null)\n                    {\n                        tunDNS = Utils.GetEmbedText(Global.TunSingboxDNSFileName);\n                    }\n                    dns4Sbox = Utils.FromJson<Dns4Sbox>(tunDNS);\n                }\n                else\n                {\n                    var item = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);\n                    var normalDNS = item?.normalDNS;\n                    if (string.IsNullOrWhiteSpace(normalDNS))\n                    {\n                        normalDNS = \"{\\\"servers\\\":[{\\\"address\\\":\\\"tcp://8.8.8.8\\\"}]}\";\n                    }\n\n                    dns4Sbox = Utils.FromJson<Dns4Sbox>(normalDNS);\n                }\n                if (dns4Sbox is null)\n                {\n                    return 0;\n                }\n                //Add the dns of the remote server domain\n                if (Utils.IsDomain(node.address))\n                {\n                    if (dns4Sbox.rules is null)\n                    {\n                        dns4Sbox.rules = new();\n                    }\n                    dns4Sbox.servers.Add(new()\n                    {\n                        tag = \"local_local\",\n                        address = \"223.5.5.5\",\n                        detour = \"direct\"\n                    });\n                    dns4Sbox.rules.Add(new()\n                    {\n                        server = \"local_local\",\n                        domain = new List<string>() { node.address }\n                    });\n                }\n\n                singboxConfig.dns = dns4Sbox;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        #endregion dns private\n\n        private int statistic(SingboxConfig singboxConfig)\n        {\n            if (_config.guiItem.enableStatistics)\n            {\n                singboxConfig.experimental = new Experimental4Sbox()\n                {\n                    v2ray_api = new V2ray_Api4Sbox()\n                    {\n                        listen = $\"{Global.Loopback}:{Global.statePort}\",\n                        stats = new Stats4Sbox()\n                        {\n                            enabled = true,\n                        }\n                    }\n                };\n            }\n            return 0;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/CoreConfigV2ray.cs",
    "content": "﻿using System.Net;\nusing System.Net.NetworkInformation;\nusing v2rayN.Base;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    internal class CoreConfigV2ray\n    {\n        private string SampleClient = Global.v2raySampleClient;\n        private Config _config;\n\n        public CoreConfigV2ray(Config config)\n        {\n            _config = config;\n        }\n\n        /*Hiddify*/\n        public int HiddifyGenerateSubConfigContent(ProfileItem node, out V2rayConfig? v2rayConfig, out string msg)\n        {\n            v2rayConfig = null;\n            try\n            {\n                if (node == null)\n                {\n                    msg = ResUI.CheckServerSettings;\n                    return -1;\n                }\n\n                msg = ResUI.InitialConfiguration;\n\n                string result = Utils.GetEmbedText(SampleClient);\n                if (Utils.IsNullOrEmpty(result))\n                {\n                    msg = ResUI.FailedGetDefaultConfiguration;\n                    return -1;\n                }\n\n                v2rayConfig = Utils.FromJson<V2rayConfig>(result);\n                if (v2rayConfig == null)\n                {\n                    msg = ResUI.FailedGenDefaultConfiguration;\n                    return -1;\n                }\n\n                log(v2rayConfig);\n\n                inbound(v2rayConfig);\n\n               \n\n\n                BalancerItem balancer = new BalancerItem();\n                balancer.tag = \"balancer\";\n                balancer.strategy = new BalancerStrategyItem();\n                if (node.configType == EConfigType.LowestPing || node.configType == EConfigType.LoadBalance)\n                {\n                    balancer.strategy.type = \"optimal\";\n                    var balancerSettings = new OptimalBalancerStrategySetting();\n                    balancerSettings.load_balancing = node.configType == EConfigType.LoadBalance;\n                    balancer.strategy.settings = balancerSettings;\n                    balancer.selector = LazyConfig.Instance.ProfileItems(node.subid).Where(p => ((int)p.configType) < 100).Select(p => \"p\" + p.indexId).ToArray();\n                }\n                routing(v2rayConfig, balancer);\n\n                \n                foreach (var p in LazyConfig.Instance.ProfileItems(node.subid))\n                {\n                    outbound(p, v2rayConfig, \"p\" + p.indexId, true);\n                }\n\n                dns(v2rayConfig);\n\n                statistic(v2rayConfig);\n\n                msg = string.Format(ResUI.SuccessfulConfiguration, \"\");\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(\"GenerateClientConfig\", ex);\n                msg = ResUI.FailedGenDefaultConfiguration;\n                return -1;\n            }\n            return 0;\n        }\n        public int GenerateClientConfigContent(ProfileItem node, out V2rayConfig? v2rayConfig, out string msg)\n        {\n            v2rayConfig = null;\n            try\n            {\n                if (node == null\n                    || node.port <= 0)\n                {\n                    msg = ResUI.CheckServerSettings;\n                    return -1;\n                }\n\n                msg = ResUI.InitialConfiguration;\n\n                string result = Utils.GetEmbedText(SampleClient);\n                if (Utils.IsNullOrEmpty(result))\n                {\n                    msg = ResUI.FailedGetDefaultConfiguration;\n                    return -1;\n                }\n\n                v2rayConfig = Utils.FromJson<V2rayConfig>(result);\n                if (v2rayConfig == null)\n                {\n                    msg = ResUI.FailedGenDefaultConfiguration;\n                    return -1;\n                }\n\n                log(v2rayConfig);\n\n                inbound(v2rayConfig);\n\n                routing(v2rayConfig);\n\n                outbound(node, v2rayConfig);\n\n                dns(v2rayConfig);\n\n                statistic(v2rayConfig);\n\n                msg = string.Format(ResUI.SuccessfulConfiguration, \"\");\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(\"GenerateClientConfig4V2ray\", ex);\n                msg = ResUI.FailedGenDefaultConfiguration;\n                return -1;\n            }\n            return 0;\n        }\n\n        private int log(V2rayConfig v2rayConfig)\n        {\n            try\n            {\n                if (_config.coreBasicItem.logEnabled)\n                {\n                    var dtNow = DateTime.Now;\n                    v2rayConfig.log.loglevel = _config.coreBasicItem.loglevel;\n                    v2rayConfig.log.access = Utils.GetLogPath($\"Vaccess_{dtNow:yyyy-MM-dd}.txt\");\n                    v2rayConfig.log.error = Utils.GetLogPath($\"Verror_{dtNow:yyyy-MM-dd}.txt\");\n                }\n                else\n                {\n                    v2rayConfig.log.loglevel = _config.coreBasicItem.loglevel;\n                    v2rayConfig.log.access = \"\";\n                    v2rayConfig.log.error = \"\";\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int inbound(V2rayConfig v2rayConfig)\n        {\n            try\n            {\n                v2rayConfig.inbounds = new List<Inbounds>();\n\n                Inbounds? inbound = GetInbound(_config.inbound[0], Global.InboundSocks, 0, true);\n                v2rayConfig.inbounds.Add(inbound);\n\n                //http\n                Inbounds? inbound2 = GetInbound(_config.inbound[0], Global.InboundHttp, 1, false);\n                v2rayConfig.inbounds.Add(inbound2);\n\n                if (_config.inbound[0].allowLANConn)\n                {\n                    if (_config.inbound[0].newPort4LAN)\n                    {\n                        Inbounds inbound3 = GetInbound(_config.inbound[0], Global.InboundSocks2, 2, true);\n                        inbound3.listen = \"0.0.0.0\";\n                        v2rayConfig.inbounds.Add(inbound3);\n\n                        Inbounds inbound4 = GetInbound(_config.inbound[0], Global.InboundHttp2, 3, false);\n                        inbound4.listen = \"0.0.0.0\";\n                        v2rayConfig.inbounds.Add(inbound4);\n\n                        //auth\n                        if (!Utils.IsNullOrEmpty(_config.inbound[0].user) && !Utils.IsNullOrEmpty(_config.inbound[0].pass))\n                        {\n                            inbound3.settings.auth = \"password\";\n                            inbound3.settings.accounts = new List<AccountsItem> { new AccountsItem() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } };\n\n                            inbound4.settings.auth = \"password\";\n                            inbound4.settings.accounts = new List<AccountsItem> { new AccountsItem() { user = _config.inbound[0].user, pass = _config.inbound[0].pass } };\n                        }\n                    }\n                    else\n                    {\n                        inbound.listen = \"0.0.0.0\";\n                        inbound2.listen = \"0.0.0.0\";\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private Inbounds? GetInbound(InItem inItem, string tag, int offset, bool bSocks)\n        {\n            string result = Utils.GetEmbedText(Global.v2raySampleInbound);\n            if (Utils.IsNullOrEmpty(result))\n            {\n                return null;\n            }\n\n            var inbound = Utils.FromJson<Inbounds>(result);\n            if (inbound == null)\n            {\n                return null;\n            }\n            inbound.tag = tag;\n            inbound.port = inItem.localPort + offset;\n            inbound.protocol = bSocks ? Global.InboundSocks : Global.InboundHttp;\n            inbound.settings.udp = inItem.udpEnabled;\n            inbound.sniffing.enabled = inItem.sniffingEnabled;\n            inbound.sniffing.routeOnly = inItem.routeOnly;\n\n            return inbound;\n        }\n\n        private int routing(V2rayConfig v2rayConfig, BalancerItem balancer = null)\n        {\n            try\n            {\n                if (v2rayConfig.routing?.rules != null)\n                {\n                    if (balancer != null)\n                    {\n                        v2rayConfig.routing.balancers = new[] { balancer }.ToList();\n                    }\n                    v2rayConfig.routing.domainStrategy = _config.routingBasicItem.domainStrategy;\n                    v2rayConfig.routing.domainMatcher = Utils.IsNullOrEmpty(_config.routingBasicItem.domainMatcher) ? null : _config.routingBasicItem.domainMatcher;\n\n                    if (_config.routingBasicItem.enableRoutingAdvanced)\n                    {\n                        var routing = ConfigHandler.GetDefaultRouting(ref _config);\n                        if (routing != null)\n                        {\n                            if (!Utils.IsNullOrEmpty(routing.domainStrategy))\n                            {\n                                v2rayConfig.routing.domainStrategy = routing.domainStrategy;\n                            }\n                            var rules = Utils.FromJson<List<RulesItem>>(routing.ruleSet);\n                            foreach (var item in rules)\n                            {\n                                if (item.enabled)\n                                {\n                                    routingUserRule(item, v2rayConfig, balancer);\n                                }\n                            }\n                        }\n                    }\n                    else\n                    {\n                        var lockedItem = ConfigHandler.GetLockedRoutingItem(ref _config);\n                        if (lockedItem != null)\n                        {\n                            var rules = Utils.FromJson<List<RulesItem>>(lockedItem.ruleSet);\n                            foreach (var item in rules)\n                            {\n                                routingUserRule(item, v2rayConfig);\n                            }\n                        }\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int routingUserRule(RulesItem rules, V2rayConfig v2rayConfig, BalancerItem? balancer = null)\n        {\n            try\n            {\n                if (rules == null)\n                {\n                    return 0;\n                }\n                if (Utils.IsNullOrEmpty(rules.port))\n                {\n                    rules.port = null;\n                }\n                if (rules.domain?.Count == 0)\n                {\n                    rules.domain = null;\n                }\n                if (rules.ip?.Count == 0)\n                {\n                    rules.ip = null;\n                }\n                if (rules.protocol?.Count == 0)\n                {\n                    rules.protocol = null;\n                }\n                if (rules.inboundTag?.Count == 0)\n                {\n                    rules.inboundTag = null;\n                }\n\n                var hasDomainIp = false;\n                if (rules.domain?.Count > 0)\n                {\n                    var it = Utils.DeepCopy(rules);\n                    it.ip = null;\n                    it.type = \"field\";\n                    for (int k = it.domain.Count - 1; k >= 0; k--)\n                    {\n                        if (it.domain[k].StartsWith(\"#\"))\n                        {\n                            it.domain.RemoveAt(k);\n                        }\n                        it.domain[k] = it.domain[k].Replace(Global.RoutingRuleComma, \",\");\n                    }\n                    if (it.outboundTag == \"proxy\" && balancer != null)\n                    {\n                        it.outboundTag = null;\n                        it.balancerTag = balancer.tag;\n                    }\n                    v2rayConfig.routing.rules.Add(it);\n                    hasDomainIp = true;\n                }\n                if (rules.ip?.Count > 0)\n                {\n                    var it = Utils.DeepCopy(rules);\n                    it.domain = null;\n                    it.type = \"field\";\n                    if (it.outboundTag == \"proxy\" && balancer != null)\n                    {\n                        it.outboundTag = null;\n                        it.balancerTag = balancer.tag;\n                    }\n                    v2rayConfig.routing.rules.Add(it);\n                    hasDomainIp = true;\n                }\n                if (!hasDomainIp)\n                {\n                    if (!Utils.IsNullOrEmpty(rules.port)\n                        || (rules.protocol?.Count > 0)\n                        || (rules.inboundTag?.Count > 0)\n                        )\n                    {\n                        var it = Utils.DeepCopy(rules);\n                        it.type = \"field\";\n                        if (it.outboundTag == \"proxy\" && balancer != null)\n                        {\n                            it.outboundTag = null;\n                            it.balancerTag = balancer.tag;\n                        }\n                        v2rayConfig.routing.rules.Add(it);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int outbound(ProfileItem node, V2rayConfig v2rayConfig, String h_tag = \"proxy\", bool h_add = false)\n        {\n            try\n            {\n                Outbounds outbound = v2rayConfig.outbounds[0];\n                if (h_add)\n                {\n                    outbound = Utils.FromJson<Outbounds>(Utils.ToJson(outbound));\n                    v2rayConfig.outbounds.Add(outbound);\n                }\n                outbound.tag = h_tag;\n                if (node.configType == EConfigType.VMess)\n                {\n                    VnextItem vnextItem;\n                    if (outbound.settings.vnext.Count <= 0)\n                    {\n                        vnextItem = new VnextItem();\n                        outbound.settings.vnext.Add(vnextItem);\n                    }\n                    else\n                    {\n                        vnextItem = outbound.settings.vnext[0];\n                    }\n                    vnextItem.address = node.address;\n                    vnextItem.port = node.port;\n\n                    UsersItem usersItem;\n                    if (vnextItem.users.Count <= 0)\n                    {\n                        usersItem = new UsersItem();\n                        vnextItem.users.Add(usersItem);\n                    }\n                    else\n                    {\n                        usersItem = vnextItem.users[0];\n                    }\n                    //远程服务器用户ID\n                    usersItem.id = node.id;\n                    usersItem.alterId = node.alterId;\n                    usersItem.email = Global.userEMail;\n                    if (Global.vmessSecuritys.Contains(node.security))\n                    {\n                        usersItem.security = node.security;\n                    }\n                    else\n                    {\n                        usersItem.security = Global.DefaultSecurity;\n                    }\n\n                    //Mux\n                    outbound.mux.enabled = _config.coreBasicItem.muxEnabled;\n                    outbound.mux.concurrency = _config.coreBasicItem.muxEnabled ? 8 : -1;\n\n                    outbound.protocol = Global.vmessProtocolLite;\n                    outbound.settings.servers = null;\n                }\n                else if (node.configType == EConfigType.Shadowsocks)\n                {\n                    ServersItem serversItem;\n                    if (outbound.settings.servers.Count <= 0)\n                    {\n                        serversItem = new ServersItem();\n                        outbound.settings.servers.Add(serversItem);\n                    }\n                    else\n                    {\n                        serversItem = outbound.settings.servers[0];\n                    }\n                    serversItem.address = node.address;\n                    serversItem.port = node.port;\n                    serversItem.password = node.id;\n                    serversItem.method = LazyConfig.Instance.GetShadowsocksSecuritys(node).Contains(node.security) ? node.security : \"none\";\n\n                    serversItem.ota = false;\n                    serversItem.level = 1;\n\n                    outbound.mux.enabled = false;\n                    outbound.mux.concurrency = -1;\n\n                    outbound.protocol = Global.ssProtocolLite;\n                    outbound.settings.vnext = null;\n                }\n                else if (node.configType == EConfigType.Socks)\n                {\n                    ServersItem serversItem;\n                    if (outbound.settings.servers.Count <= 0)\n                    {\n                        serversItem = new ServersItem();\n                        outbound.settings.servers.Add(serversItem);\n                    }\n                    else\n                    {\n                        serversItem = outbound.settings.servers[0];\n                    }\n                    serversItem.address = node.address;\n                    serversItem.port = node.port;\n                    serversItem.method = null;\n                    serversItem.password = null;\n\n                    if (!Utils.IsNullOrEmpty(node.security)\n                        && !Utils.IsNullOrEmpty(node.id))\n                    {\n                        SocksUsersItem socksUsersItem = new()\n                        {\n                            user = node.security,\n                            pass = node.id,\n                            level = 1\n                        };\n\n                        serversItem.users = new List<SocksUsersItem>() { socksUsersItem };\n                    }\n\n                    outbound.mux.enabled = false;\n                    outbound.mux.concurrency = -1;\n\n                    outbound.protocol = Global.socksProtocolLite;\n                    outbound.settings.vnext = null;\n                }\n                else if (node.configType == EConfigType.VLESS)\n                {\n                    VnextItem vnextItem;\n                    if (outbound.settings.vnext.Count <= 0)\n                    {\n                        vnextItem = new VnextItem();\n                        outbound.settings.vnext.Add(vnextItem);\n                    }\n                    else\n                    {\n                        vnextItem = outbound.settings.vnext[0];\n                    }\n                    vnextItem.address = node.address;\n                    vnextItem.port = node.port;\n\n                    UsersItem usersItem;\n                    if (vnextItem.users.Count <= 0)\n                    {\n                        usersItem = new UsersItem();\n                        vnextItem.users.Add(usersItem);\n                    }\n                    else\n                    {\n                        usersItem = vnextItem.users[0];\n                    }\n                    usersItem.id = node.id;\n                    usersItem.flow = string.Empty;\n                    usersItem.email = Global.userEMail;\n                    usersItem.encryption = node.security;\n\n                    //Mux\n                    outbound.mux.enabled = _config.coreBasicItem.muxEnabled;\n                    outbound.mux.concurrency = _config.coreBasicItem.muxEnabled ? 8 : -1;\n\n                    if (node.streamSecurity == Global.StreamSecurityReality\n                        || node.streamSecurity == Global.StreamSecurity)\n                    {\n                        if (!Utils.IsNullOrEmpty(node.flow))\n                        {\n                            usersItem.flow = node.flow;\n\n                            outbound.mux.enabled = false;\n                            outbound.mux.concurrency = -1;\n                        }\n                    }\n\n                    outbound.protocol = Global.vlessProtocolLite;\n                    outbound.settings.servers = null;\n                }\n                else if (node.configType == EConfigType.Trojan)\n                {\n                    ServersItem serversItem;\n                    if (outbound.settings.servers.Count <= 0)\n                    {\n                        serversItem = new ServersItem();\n                        outbound.settings.servers.Add(serversItem);\n                    }\n                    else\n                    {\n                        serversItem = outbound.settings.servers[0];\n                    }\n                    serversItem.address = node.address;\n                    serversItem.port = node.port;\n                    serversItem.password = node.id;\n                    serversItem.flow = string.Empty;\n\n                    serversItem.ota = false;\n                    serversItem.level = 1;\n\n                    outbound.mux.enabled = false;\n                    outbound.mux.concurrency = -1;\n\n                    outbound.protocol = Global.trojanProtocolLite;\n                    outbound.settings.vnext = null;\n                }\n                boundStreamSettings(node, outbound.streamSettings);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int boundStreamSettings(ProfileItem node, StreamSettings streamSettings)\n        {\n            try\n            {\n                streamSettings.network = node.GetNetwork();\n                string host = node.requestHost.TrimEx();\n                string sni = node.sni;\n                string useragent = \"\";\n                if (!_config.coreBasicItem.defUserAgent.IsNullOrEmpty())\n                {\n                    try\n                    {\n                        useragent = Global.userAgentTxt[_config.coreBasicItem.defUserAgent];\n                    }\n                    catch (KeyNotFoundException)\n                    {\n                        useragent = _config.coreBasicItem.defUserAgent;\n                    }\n                }\n\n                //if tls\n                if (node.streamSecurity == Global.StreamSecurity)\n                {\n                    streamSettings.security = node.streamSecurity;\n\n                    TlsSettings tlsSettings = new()\n                    {\n                        allowInsecure = Utils.ToBool(node.allowInsecure.IsNullOrEmpty() ? _config.coreBasicItem.defAllowInsecure.ToString().ToLower() : node.allowInsecure),\n                        alpn = node.GetAlpn(),\n                        fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.coreBasicItem.defFingerprint : node.fingerprint\n                    };\n                    if (!string.IsNullOrWhiteSpace(sni))\n                    {\n                        tlsSettings.serverName = sni;\n                    }\n                    else if (!string.IsNullOrWhiteSpace(host))\n                    {\n                        tlsSettings.serverName = Utils.String2List(host)[0];\n                    }\n                    streamSettings.tlsSettings = tlsSettings;\n                }\n\n                //if Reality\n                if (node.streamSecurity == Global.StreamSecurityReality)\n                {\n                    streamSettings.security = node.streamSecurity;\n\n                    TlsSettings realitySettings = new()\n                    {\n                        fingerprint = node.fingerprint.IsNullOrEmpty() ? _config.coreBasicItem.defFingerprint : node.fingerprint,\n                        serverName = sni,\n                        publicKey = node.publicKey,\n                        shortId = node.shortId,\n                        spiderX = node.spiderX,\n                    };\n\n                    streamSettings.realitySettings = realitySettings;\n                }\n\n                //streamSettings\n                switch (node.GetNetwork())\n                {\n                    case \"kcp\":\n                        KcpSettings kcpSettings = new()\n                        {\n                            mtu = _config.kcpItem.mtu,\n                            tti = _config.kcpItem.tti\n                        };\n\n                        kcpSettings.uplinkCapacity = _config.kcpItem.uplinkCapacity;\n                        kcpSettings.downlinkCapacity = _config.kcpItem.downlinkCapacity;\n\n                        kcpSettings.congestion = _config.kcpItem.congestion;\n                        kcpSettings.readBufferSize = _config.kcpItem.readBufferSize;\n                        kcpSettings.writeBufferSize = _config.kcpItem.writeBufferSize;\n                        kcpSettings.header = new Header\n                        {\n                            type = node.headerType\n                        };\n                        if (!Utils.IsNullOrEmpty(node.path))\n                        {\n                            kcpSettings.seed = node.path;\n                        }\n                        streamSettings.kcpSettings = kcpSettings;\n                        break;\n                    //ws\n                    case \"ws\":\n                        WsSettings wsSettings = new();\n                        wsSettings.headers = new Headers();\n                        string path = node.path;\n                        if (!string.IsNullOrWhiteSpace(host))\n                        {\n                            wsSettings.headers.Host = host;\n                        }\n                        if (!string.IsNullOrWhiteSpace(path))\n                        {\n                            wsSettings.path = path;\n                        }\n                        if (!string.IsNullOrWhiteSpace(useragent))\n                        {\n                            wsSettings.headers.UserAgent = useragent;\n                        }\n                        if (!node.fragment.IsNullOrEmpty()) {\n                            wsSettings.fragmentation = new FragmentationConfig();\n                            wsSettings.fragmentation.strategy = node.fragment;\n\n                        }\n                        streamSettings.wsSettings = wsSettings;\n\n                        break;\n                    //h2\n                    case \"h2\":\n                        HttpSettings httpSettings = new();\n\n                        if (!string.IsNullOrWhiteSpace(host))\n                        {\n                            httpSettings.host = Utils.String2List(host);\n                        }\n                        httpSettings.path = node.path;\n\n                        streamSettings.httpSettings = httpSettings;\n\n                        break;\n                    //quic\n                    case \"quic\":\n                        QuicSettings quicsettings = new()\n                        {\n                            security = host,\n                            key = node.path,\n                            header = new Header\n                            {\n                                type = node.headerType\n                            }\n                        };\n                        streamSettings.quicSettings = quicsettings;\n                        if (node.streamSecurity == Global.StreamSecurity)\n                        {\n                            if (!string.IsNullOrWhiteSpace(sni))\n                            {\n                                streamSettings.tlsSettings.serverName = sni;\n                            }\n                            else\n                            {\n                                streamSettings.tlsSettings.serverName = node.address;\n                            }\n                        }\n                        break;\n\n                    case \"grpc\":\n                        GrpcSettings grpcSettings = new()\n                        {\n                            serviceName = node.path,\n                            multiMode = (node.headerType == Global.GrpcmultiMode),\n                            idle_timeout = _config.grpcItem.idle_timeout,\n                            health_check_timeout = _config.grpcItem.health_check_timeout,\n                            permit_without_stream = _config.grpcItem.permit_without_stream,\n                            initial_windows_size = _config.grpcItem.initial_windows_size,\n                        };\n                        streamSettings.grpcSettings = grpcSettings;\n                        break;\n\n                    default:\n                        //tcp\n                        if (node.headerType == Global.TcpHeaderHttp)\n                        {\n                            TcpSettings tcpSettings = new()\n                            {\n                                header = new Header\n                                {\n                                    type = node.headerType\n                                }\n                            };\n\n                            //request Host\n                            string request = Utils.GetEmbedText(Global.v2raySampleHttprequestFileName);\n                            string[] arrHost = host.Split(',');\n                            string host2 = string.Join(\"\\\",\\\"\", arrHost);\n                            request = request.Replace(\"$requestHost$\", $\"\\\"{host2}\\\"\");\n                            //request = request.Replace(\"$requestHost$\", string.Format(\"\\\"{0}\\\"\", config.requestHost()));\n                            request = request.Replace(\"$requestUserAgent$\", $\"\\\"{useragent}\\\"\");\n                            //Path\n                            string pathHttp = @\"/\";\n                            if (!Utils.IsNullOrEmpty(node.path))\n                            {\n                                string[] arrPath = node.path.Split(',');\n                                pathHttp = string.Join(\"\\\",\\\"\", arrPath);\n                            }\n                            request = request.Replace(\"$requestPath$\", $\"\\\"{pathHttp}\\\"\");\n                            tcpSettings.header.request = Utils.FromJson<object>(request);\n\n                            streamSettings.tcpSettings = tcpSettings;\n                        }\n                        break;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int dns(V2rayConfig v2rayConfig)\n        {\n            try\n            {\n                var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);\n                var normalDNS = item?.normalDNS;\n                var domainStrategy4Freedom = item?.domainStrategy4Freedom;\n                if (string.IsNullOrWhiteSpace(normalDNS))\n                {\n                    normalDNS = \"1.1.1.1,8.8.8.8\";\n                }\n\n                //Outbound Freedom domainStrategy\n                if (!string.IsNullOrWhiteSpace(domainStrategy4Freedom))\n                {\n                    var outbound = v2rayConfig.outbounds[1];\n                    outbound.settings.domainStrategy = domainStrategy4Freedom;\n                    outbound.settings.userLevel = 0;\n                }\n\n                var obj = Utils.ParseJson(normalDNS);\n                if (obj?.ContainsKey(\"servers\") == true)\n                {\n                    v2rayConfig.dns = obj;\n                }\n                else\n                {\n                    List<string> servers = new();\n\n                    string[] arrDNS = normalDNS.Split(',');\n                    foreach (string str in arrDNS)\n                    {\n                        //if (Utils.IsIP(str))\n                        //{\n                        servers.Add(str);\n                        //}\n                    }\n                    //servers.Add(\"localhost\");\n                    v2rayConfig.dns = new Mode.Dns\n                    {\n                        servers = servers\n                    };\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return 0;\n        }\n\n        private int statistic(V2rayConfig v2rayConfig)\n        {\n            if (_config.guiItem.enableStatistics)\n            {\n                string tag = Global.InboundAPITagName;\n                API apiObj = new();\n                Policy policyObj = new();\n                SystemPolicy policySystemSetting = new();\n\n                string[] services = { \"StatsService\" };\n\n                v2rayConfig.stats = new Stats();\n\n                apiObj.tag = tag;\n                apiObj.services = services.ToList();\n                v2rayConfig.api = apiObj;\n\n                policySystemSetting.statsOutboundDownlink = true;\n                policySystemSetting.statsOutboundUplink = true;\n                policyObj.system = policySystemSetting;\n                v2rayConfig.policy = policyObj;\n\n                if (!v2rayConfig.inbounds.Exists(item => item.tag == tag))\n                {\n                    Inbounds apiInbound = new();\n                    Inboundsettings apiInboundSettings = new();\n                    apiInbound.tag = tag;\n                    apiInbound.listen = Global.Loopback;\n                    apiInbound.port = Global.statePort;\n                    apiInbound.protocol = Global.InboundAPIProtocal;\n                    apiInboundSettings.address = Global.Loopback;\n                    apiInbound.settings = apiInboundSettings;\n                    v2rayConfig.inbounds.Add(apiInbound);\n                }\n\n                if (!v2rayConfig.routing.rules.Exists(item => item.outboundTag == tag))\n                {\n                    RulesItem apiRoutingRule = new()\n                    {\n                        inboundTag = new List<string> { tag },\n                        outboundTag = tag,\n                        type = \"field\"\n                    };\n                    v2rayConfig.routing.rules.Add(apiRoutingRule);\n                }\n            }\n            return 0;\n        }\n\n        #region Gen speedtest config\n\n        public string GenerateClientSpeedtestConfigString(List<ServerTestItem> selecteds, out string msg)\n        {\n            try\n            {\n                if (_config == null)\n                {\n                    msg = ResUI.CheckServerSettings;\n                    return \"\";\n                }\n\n                msg = ResUI.InitialConfiguration;\n\n                Config configCopy = Utils.DeepCopy(_config);\n\n                string result = Utils.GetEmbedText(SampleClient);\n                if (Utils.IsNullOrEmpty(result))\n                {\n                    msg = ResUI.FailedGetDefaultConfiguration;\n                    return \"\";\n                }\n\n                V2rayConfig? v2rayConfig = Utils.FromJson<V2rayConfig>(result);\n                if (v2rayConfig == null)\n                {\n                    msg = ResUI.FailedGenDefaultConfiguration;\n                    return \"\";\n                }\n                List<IPEndPoint> lstIpEndPoints = new();\n                List<TcpConnectionInformation> lstTcpConns = new();\n                try\n                {\n                    lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());\n                    lstIpEndPoints.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveUdpListeners());\n                    lstTcpConns.AddRange(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpConnections());\n                }\n                catch (Exception ex)\n                {\n                    Utils.SaveLog(ex.Message, ex);\n                }\n\n                log(v2rayConfig);\n                v2rayConfig.inbounds.Clear(); // Remove \"proxy\" service for speedtest, avoiding port conflicts.\n\n                int httpPort = LazyConfig.Instance.GetLocalPort(\"speedtest\");\n\n                foreach (var it in selecteds)\n                {\n                    if (it.configType == EConfigType.Custom)\n                    {\n                        continue;\n                    }\n                    if (it.port <= 0 && (int)it.configType < 100)\n                    {\n                        continue;\n                    }\n                    if (it.configType is EConfigType.VMess or EConfigType.VLESS)\n                    {\n                        var item2 = LazyConfig.Instance.GetProfileItem(it.indexId);\n                        if (item2 is null || Utils.IsNullOrEmpty(item2.id) || !Utils.IsGuidByParse(item2.id))\n                        {\n                            continue;\n                        }\n                    }\n\n                    //find unuse port\n                    var port = httpPort;\n                    for (int k = httpPort; k < Global.MaxPort; k++)\n                    {\n                        if (lstIpEndPoints?.FindIndex(_it => _it.Port == k) >= 0)\n                        {\n                            continue;\n                        }\n                        if (lstTcpConns?.FindIndex(_it => _it.LocalEndPoint.Port == k) >= 0)\n                        {\n                            continue;\n                        }\n                        //found\n                        port = k;\n                        httpPort = port + 1;\n                        break;\n                    }\n\n                    //Port In Used\n                    if (lstIpEndPoints?.FindIndex(_it => _it.Port == port) >= 0)\n                    {\n                        continue;\n                    }\n                    it.port = port;\n                    it.allowTest = true;\n\n                    //inbound\n                    Inbounds inbound = new()\n                    {\n                        listen = Global.Loopback,\n                        port = port,\n                        protocol = Global.InboundHttp\n                    };\n                    inbound.tag = Global.InboundHttp + inbound.port.ToString();\n                    v2rayConfig.inbounds.Add(inbound);\n\n                    //outbound\n                    V2rayConfig? v2rayConfigCopy = Utils.FromJson<V2rayConfig>(result);\n                    var item = LazyConfig.Instance.GetProfileItem(it.indexId);\n                    if (item is null)\n                    {\n                        continue;\n                    }\n                    if (item.configType == EConfigType.Shadowsocks\n                        && !Global.ssSecuritysInXray.Contains(item.security))\n                    {\n                        continue;\n                    }\n                    if (item.configType == EConfigType.VLESS\n                     && !Global.flows.Contains(item.flow))\n                    {\n                        continue;\n                    }\n                    if (item.configType == EConfigType.LowestPing || item.configType == EConfigType.LoadBalance)\n                    {\n                        var balancer = new BalancerItem();\n                        balancer.tag = \"balancer\" + inbound.port.ToString();\n                        balancer.strategy = new BalancerStrategyItem();\n                        if (item.configType == EConfigType.LowestPing || item.configType == EConfigType.LoadBalance)\n                        {\n                            balancer.strategy.type = \"optimal\";\n                            var balancerSettings = new OptimalBalancerStrategySetting();\n                            balancerSettings.load_balancing = item.configType == EConfigType.LoadBalance;\n                            balancer.strategy.settings = balancerSettings;\n                            balancer.selector = LazyConfig.Instance.ProfileItems(item.subid).Where(p => ((int)p.configType) < 100).Select(p => \"p\" + p.indexId).ToArray();\n                        }\n\n                        v2rayConfig.routing.balancers.Add(balancer);\n\n                        if (v2rayConfig.routing.balancers.Count == 1)\n                        {\n                            foreach (var p in LazyConfig.Instance.ProfileItems(item.subid))\n                            {\n                                outbound(p, v2rayConfig, \"p\" + p.indexId, true);\n                            }\n                        }\n\n                        //rule\n                        RulesItem rule = new()\n                        {\n                            inboundTag = new List<string> { inbound.tag },\n                            balancerTag = balancer.tag,\n                            type = \"field\"\n                        };\n                        v2rayConfig.routing.rules.Add(rule);\n                    }\n                    else\n                    {\n                        outbound(item, v2rayConfigCopy);\n                        v2rayConfigCopy.outbounds[0].tag = Global.agentTag + inbound.port.ToString();\n                        v2rayConfig.outbounds.Add(v2rayConfigCopy.outbounds[0]);\n\n                        //rule\n                        RulesItem rule = new()\n                        {\n                            inboundTag = new List<string> { inbound.tag },\n                            outboundTag = v2rayConfigCopy.outbounds[0].tag,\n                            type = \"field\"\n                        };\n                        v2rayConfig.routing.rules.Add(rule);\n                    }\n                }\n\n                //msg = string.Format(ResUI.SuccessfulConfiguration\"), node.getSummary());\n                return Utils.ToJson(v2rayConfig);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                msg = ResUI.FailedGenDefaultConfiguration;\n                return \"\";\n            }\n        }\n\n        #endregion Gen speedtest config\n    \n    \n    }\n\n\n\n    \n\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/CoreHandler.cs",
    "content": "﻿using System.Diagnostics;\nusing System.IO;\nusing System.Text;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    /// <summary>\n    /// Core process processing class\n    /// </summary>\n    internal class CoreHandler\n    {\n        private Config _config;\n        private CoreInfo? _coreInfo;\n        private Process? _process;\n        private Process? _processPre;\n        private Action<bool, string> _updateFunc;\n\n        public CoreHandler(Config config, Action<bool, string> update)\n        {\n            _config = config;\n            _updateFunc = update;\n\n            Environment.SetEnvironmentVariable(\"v2ray.location.asset\", Utils.GetBinPath(\"\"), EnvironmentVariableTarget.Process);\n            Environment.SetEnvironmentVariable(\"xray.location.asset\", Utils.GetBinPath(\"\"), EnvironmentVariableTarget.Process);\n        }\n\n        public void LoadCore()\n        {\n            var node = ConfigHandler.GetDefaultServer(ref _config);\n            if (node == null)\n            {\n                ShowMsg(false, ResUI.CheckServerSettings);\n                return;\n            }\n\n            if (SetCore(node) != 0)\n            {\n                ShowMsg(false, ResUI.CheckServerSettings);\n                return;\n            }\n            string fileName = Utils.GetConfigPath(Global.coreConfigFileName);\n            if (CoreConfigHandler.GenerateClientConfig(node, fileName, out string msg, out string content) != 0)\n            {\n                ShowMsg(false, msg);\n            }\n            else\n            {\n                ShowMsg(false, msg);\n                ShowMsg(true, $\"{node.GetSummary()}\");\n                CoreStop();\n                CoreStart(node);\n            }\n        }\n\n        public int LoadCoreConfigString(List<ServerTestItem> _selecteds)\n        {\n            int pid = -1;\n            string configStr = CoreConfigHandler.GenerateClientSpeedtestConfigString(_config, _selecteds, out string msg);\n            if (configStr == \"\")\n            {\n                ShowMsg(false, msg);\n            }\n            else\n            {\n                ShowMsg(false, msg);\n                pid = CoreStartViaString(configStr);\n            }\n            return pid;\n        }\n\n        public void CoreStop()\n        {\n            try\n            {\n                if (_process != null)\n                {\n                    KillProcess(_process);\n                    _process.Dispose();\n                    _process = null;\n                }\n                else\n                {\n                    if (_coreInfo == null || _coreInfo.coreExes == null)\n                    {\n                        return;\n                    }\n                    foreach (string vName in _coreInfo.coreExes)\n                    {\n                        Process[] existing = Process.GetProcessesByName(vName);\n                        foreach (Process p in existing)\n                        {\n                            string? path = p.MainModule?.FileName;\n                            if (path == $\"{Utils.GetBinPath(vName, _coreInfo.coreType)}.exe\")\n                            {\n                                KillProcess(p);\n                            }\n                        }\n                    }\n                }\n\n                if (_processPre != null)\n                {\n                    KillProcess(_processPre);\n                    _processPre.Dispose();\n                    _processPre = null;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        public void CoreStopPid(int pid)\n        {\n            try\n            {\n                Process _p = Process.GetProcessById(pid);\n                KillProcess(_p);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private string CoreFindexe(CoreInfo coreInfo)\n        {\n            string fileName = string.Empty;\n            foreach (string name in coreInfo.coreExes)\n            {\n                string vName = $\"{name}.exe\";\n                vName = Utils.GetBinPath(vName, coreInfo.coreType);\n                if (File.Exists(vName))\n                {\n                    fileName = vName;\n                    break;\n                }\n            }\n            if (Utils.IsNullOrEmpty(fileName))\n            {\n                string msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath(\"\", coreInfo.coreType), string.Join(\", \", coreInfo.coreExes.ToArray()), coreInfo.coreUrl);\n                Utils.SaveLog(msg);\n                ShowMsg(false, msg);\n            }\n            return fileName;\n        }\n\n        private void CoreStart(ProfileItem node)\n        {\n            ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString()));\n\n            var proc = RunProcess(node, _coreInfo, \"\", ShowMsg);\n            if (proc is null)\n            {\n                return;\n            }\n            _process = proc;\n\n            //start a socks service\n            if (_process != null && !_process.HasExited)\n            {\n                if ((node.configType == EConfigType.Custom && node.preSocksPort > 0)\n                    || (node.configType != EConfigType.Custom && _coreInfo.coreType != ECoreType.sing_box && _config.tunModeItem.enableTun))\n                {\n                    var itemSocks = new ProfileItem()\n                    {\n                        coreType = ECoreType.sing_box,\n                        configType = EConfigType.Socks,\n                        address = Global.Loopback,\n                        port = node.preSocksPort > 0 ? node.preSocksPort : LazyConfig.Instance.GetLocalPort(Global.InboundSocks)\n                    };\n                    string fileName2 = Utils.GetConfigPath(Global.corePreConfigFileName);\n                    if (CoreConfigHandler.GenerateClientConfig(itemSocks, fileName2, out string msg2, out string configStr) == 0)\n                    {\n                        var coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box);\n                        var proc2 = RunProcess(node, coreInfo, $\" -c {Global.corePreConfigFileName}\", ShowMsg);\n                        if (proc2 is not null)\n                        {\n                            _processPre = proc2;\n                        }\n                    }\n                }\n            }\n        }\n\n        private int CoreStartViaString(string configStr)\n        {\n            ShowMsg(false, string.Format(ResUI.StartService, DateTime.Now.ToString()));\n\n            try\n            {\n                var coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.Xray);\n                string fileName = CoreFindexe(coreInfo);\n                if (fileName == \"\") return -1;\n\n                Process p = new()\n                {\n                    StartInfo = new ProcessStartInfo\n                    {\n                        FileName = fileName,\n                        Arguments = \"-config stdin:\",\n                        WorkingDirectory = Utils.GetConfigPath(),\n                        UseShellExecute = false,\n                        RedirectStandardInput = true,\n                        RedirectStandardOutput = true,\n                        RedirectStandardError = true,\n                        CreateNoWindow = true,\n                        StandardOutputEncoding = Encoding.UTF8,\n                        StandardErrorEncoding = Encoding.UTF8\n                    }\n                };\n                p.OutputDataReceived += (sender, e) =>\n                {\n                    if (!String.IsNullOrEmpty(e.Data))\n                    {\n                        string msg = e.Data + Environment.NewLine;\n                        ShowMsg(false, msg);\n                    }\n                };\n                p.ErrorDataReceived += (sender, e) =>\n                {\n                    if (!string.IsNullOrEmpty(e.Data))\n                    {\n                        string msg = e.Data + Environment.NewLine;\n                        ShowMsg(false, msg);\n                    }\n                };\n                p.Start();\n                p.BeginOutputReadLine();\n                p.BeginErrorReadLine();\n\n                p.StandardInput.Write(configStr);\n                p.StandardInput.Close();\n\n                if (p.WaitForExit(1000))\n                {\n                    throw new Exception(p.StandardError.ReadToEnd());\n                }\n\n                Global.processJob.AddProcess(p.Handle);\n                return p.Id;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                string msg = ex.Message;\n                ShowMsg(false, msg);\n                return -1;\n            }\n        }\n\n        private void ShowMsg(bool updateToTrayTooltip, string msg)\n        {\n            _updateFunc(updateToTrayTooltip, msg);\n        }\n\n        private int SetCore(ProfileItem node)\n        {\n            if (node == null)\n            {\n                return -1;\n            }\n            var coreType = LazyConfig.Instance.GetCoreType(node, node.configType);\n\n            _coreInfo = LazyConfig.Instance.GetCoreInfo(coreType);\n\n            if (_coreInfo == null)\n            {\n                return -1;\n            }\n            return 0;\n        }\n\n        #region Process\n\n        private Process? RunProcess(ProfileItem node, CoreInfo coreInfo, string configPath, Action<bool, string> update)\n        {\n            try\n            {\n                string fileName = CoreFindexe(coreInfo);\n                if (Utils.IsNullOrEmpty(fileName))\n                {\n                    return null;\n                }\n                var displayLog = node.configType != EConfigType.Custom || node.displayLog;\n                Process proc = new()\n                {\n                    StartInfo = new ProcessStartInfo\n                    {\n                        FileName = fileName,\n                        Arguments = string.Format(coreInfo.arguments, configPath),\n                        WorkingDirectory = Utils.GetConfigPath(),\n                        UseShellExecute = false,\n                        RedirectStandardOutput = displayLog,\n                        RedirectStandardError = displayLog,\n                        CreateNoWindow = true,\n                        StandardOutputEncoding = displayLog ? Encoding.UTF8 : null,\n                        StandardErrorEncoding = displayLog ? Encoding.UTF8 : null,\n                    }\n                };\n                if (displayLog)\n                {\n                    proc.OutputDataReceived += (sender, e) =>\n                    {\n                        if (!string.IsNullOrEmpty(e.Data))\n                        {\n                            string msg = e.Data + Environment.NewLine;\n                            update(false, msg);\n                        }\n                    };\n                    proc.ErrorDataReceived += (sender, e) =>\n                    {\n                        if (!string.IsNullOrEmpty(e.Data))\n                        {\n                            string msg = e.Data + Environment.NewLine;\n                            update(false, msg);\n                        }\n                    };\n                }\n                proc.Start();\n                if (displayLog)\n                {\n                    proc.BeginOutputReadLine();\n                    proc.BeginErrorReadLine();\n                }\n\n                if (proc.WaitForExit(1000))\n                {\n                    throw new Exception(displayLog ? proc.StandardError.ReadToEnd() : \"启动进程失败并退出 (Failed to start the process and exited)\");\n                }\n\n                Global.processJob.AddProcess(proc.Handle);\n                return proc;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                string msg = ex.Message;\n                update(true, msg);\n                return null;\n            }\n        }\n\n        private void KillProcess(Process p)\n        {\n            try\n            {\n                p.CloseMainWindow();\n                p.WaitForExit(100);\n                if (!p.HasExited)\n                {\n                    p.Kill();\n                    p.WaitForExit(100);\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        #endregion Process\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/DownloadHandle.cs",
    "content": "﻿using System.Diagnostics;\nusing System.IO;\nusing System.Net;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Net.Sockets;\nusing v2rayN.Base;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    /// <summary>\n    ///Download\n    /// </summary>\n    internal class DownloadHandle\n    {\n        public event EventHandler<ResultEventArgs>? UpdateCompleted;\n\n        public event ErrorEventHandler? Error;\n\n        public class ResultEventArgs : EventArgs\n        {\n            public bool Success;\n            public string Msg;\n\n            public ResultEventArgs(bool success, string msg)\n            {\n                Success = success;\n                Msg = msg;\n            }\n        }\n\n        public async Task<int> DownloadDataAsync(string url, WebProxy webProxy, int downloadTimeout, Action<bool, string> update)\n        {\n            try\n            {\n                Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);\n\n                var progress = new Progress<string>();\n                progress.ProgressChanged += (sender, value) =>\n                {\n                    if (update != null)\n                    {\n                        string msg = $\"{value}\";\n                        update(false, msg);\n                    }\n                };\n\n                await DownloaderHelper.Instance.DownloadDataAsync4Speed(webProxy,\n                      url,\n                      progress,\n                      downloadTimeout);\n            }\n            catch (Exception ex)\n            {\n                update(false, ex.Message);\n                if (ex.InnerException != null)\n                {\n                    update(false, ex.InnerException.Message);\n                }\n            }\n            return 0;\n        }\n\n        public async Task DownloadFileAsync(string url, bool blProxy, int downloadTimeout)\n        {\n            try\n            {\n                Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);\n                UpdateCompleted?.Invoke(this, new ResultEventArgs(false, $\"{ResUI.Downloading}   {url}\"));\n\n                var progress = new Progress<double>();\n                progress.ProgressChanged += (sender, value) =>\n                {\n                    UpdateCompleted?.Invoke(this, new ResultEventArgs(value > 100, $\"...{value}%\"));\n                };\n\n                var webProxy = GetWebProxy(blProxy);\n                await DownloaderHelper.Instance.DownloadFileAsync(webProxy,\n                    url,\n                    Utils.GetTempPath(Utils.GetDownloadFileName(url)),\n                    progress,\n                    downloadTimeout);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n\n                Error?.Invoke(this, new ErrorEventArgs(ex));\n                if (ex.InnerException != null)\n                {\n                    Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));\n                }\n            }\n        }\n\n        public async Task<string?> UrlRedirectAsync(string url, bool blProxy)\n        {\n            Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);\n            var webRequestHandler = new SocketsHttpHandler\n            {\n                AllowAutoRedirect = false,\n                Proxy = GetWebProxy(blProxy)\n            };\n            HttpClient client = new(webRequestHandler);\n\n            HttpResponseMessage response = await client.GetAsync(url);\n            if (response.StatusCode == HttpStatusCode.Redirect && response.Headers.Location is not null)\n            {\n                return response.Headers.Location.ToString();\n            }\n            else\n            {\n                Utils.SaveLog(\"StatusCode error: \" + url);\n                return null;\n            }\n        }\n\n        public async Task<string?> TryDownloadString(string url, bool blProxy, string userAgent)\n        {\n            try\n            {\n                var result1 = await DownloadStringAsync(url, blProxy, userAgent);\n                if (!Utils.IsNullOrEmpty(result1))\n                {\n                    return result1;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                Error?.Invoke(this, new ErrorEventArgs(ex));\n                if (ex.InnerException != null)\n                {\n                    Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));\n                }\n            }\n\n            try\n            {\n                var result2 = await DownloadStringViaDownloader(url, blProxy, userAgent);\n                if (!Utils.IsNullOrEmpty(result2))\n                {\n                    return result2;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                Error?.Invoke(this, new ErrorEventArgs(ex));\n                if (ex.InnerException != null)\n                {\n                    Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));\n                }\n            }\n\n            try\n            {\n                using var wc = new WebClient();\n                wc.Proxy = GetWebProxy(blProxy);\n                var result3 = await wc.DownloadStringTaskAsync(url);\n                if (!Utils.IsNullOrEmpty(result3))\n                {\n                    return result3;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                Error?.Invoke(this, new ErrorEventArgs(ex));\n                if (ex.InnerException != null)\n                {\n                    Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));\n                }\n            }\n\n            return null;\n        }\n\n        /// <summary>\n        /// DownloadString\n        /// </summary>\n        /// <param name=\"url\"></param>\n        public async Task<string?> DownloadStringAsync(string url, bool blProxy, string userAgent)\n        {\n            try\n            {\n                Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);\n                var webProxy = GetWebProxy(blProxy);\n                var client = new HttpClient(new SocketsHttpHandler()\n                {\n                    Proxy = webProxy,\n                    UseProxy = webProxy != null\n                });\n\n                if (Utils.IsNullOrEmpty(userAgent))\n                {\n                    userAgent = Utils.GetVersion(false);\n                }\n                client.DefaultRequestHeaders.UserAgent.TryParseAdd(userAgent);\n\n                Uri uri = new(url);\n                //Authorization Header\n                if (!Utils.IsNullOrEmpty(uri.UserInfo))\n                {\n                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(\"Basic\", Utils.Base64Encode(uri.UserInfo));\n                }\n\n                using var cts = new CancellationTokenSource();\n                var result = await HttpClientHelper.Instance.GetAsync(client, url, cts.Token).WaitAsync(TimeSpan.FromSeconds(30), cts.Token);\n                return result;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                Error?.Invoke(this, new ErrorEventArgs(ex));\n                if (ex.InnerException != null)\n                {\n                    Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));\n                }\n            }\n            return null;\n        }\n\n        /// <summary>\n        /// DownloadString\n        /// </summary>\n        /// <param name=\"url\"></param>\n        public async Task<string?> DownloadStringViaDownloader(string url, bool blProxy, string userAgent)\n        {\n            try\n            {\n                Utils.SetSecurityProtocol(LazyConfig.Instance.GetConfig().guiItem.enableSecurityProtocolTls13);\n\n                var webProxy = GetWebProxy(blProxy);\n\n                if (Utils.IsNullOrEmpty(userAgent))\n                {\n                    userAgent = Utils.GetVersion(false);\n                }\n                var result = await DownloaderHelper.Instance.DownloadStringAsync(webProxy, url, userAgent, 30);\n                return result;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                Error?.Invoke(this, new ErrorEventArgs(ex));\n                if (ex.InnerException != null)\n                {\n                    Error?.Invoke(this, new ErrorEventArgs(ex.InnerException));\n                }\n            }\n            return null;\n        }\n\n        public async Task<int> RunAvailabilityCheck(IWebProxy? webProxy,int count=3)\n        {\n            int responseTime = -1;\n            try\n            {\n                if (webProxy == null)\n                {\n                    webProxy = GetWebProxy(true);\n                }\n\n                \n                var config = LazyConfig.Instance.GetConfig();\n                responseTime = await GetRealPingTime(config.speedTestItem.speedPingTestUrl, webProxy, 10);\n                if (count == 3)\n                    responseTime = -1;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                responseTime = -1;\n            }\n            if (responseTime < 0 && count > 0)\n            {\n                await Task.Delay(500);\n                await RunAvailabilityCheck(webProxy, count - 1);\n            }\n\n            return responseTime;\n        }\n\n        public async Task<int> GetRealPingTime(string url, IWebProxy? webProxy, int downloadTimeout)\n        {\n            int responseTime = -1;\n            try\n            {\n                Stopwatch timer = Stopwatch.StartNew();\n\n                using var cts = new CancellationTokenSource();\n                cts.CancelAfter(TimeSpan.FromSeconds(downloadTimeout));\n                using var client = new HttpClient(new SocketsHttpHandler()\n                {\n                    Proxy = webProxy,\n                    UseProxy = webProxy != null\n                });\n                await client.GetAsync(url, cts.Token);\n\n                responseTime = timer.Elapsed.Milliseconds;\n            }\n            catch (Exception ex)\n            {\n                //Utils.SaveLog(ex.Message, ex);\n            }\n            return responseTime;\n        }\n\n        private WebProxy? GetWebProxy(bool blProxy)\n        {\n            if (!blProxy)\n            {\n                return null;\n            }\n            var httpPort = LazyConfig.Instance.GetLocalPort(Global.InboundHttp);\n            if (!SocketCheck(Global.Loopback, httpPort))\n            {\n                return null;\n            }\n\n            return new WebProxy(Global.Loopback, httpPort);\n        }\n\n        private bool SocketCheck(string ip, int port)\n        {\n            try\n            {\n                IPEndPoint point = new(IPAddress.Parse(ip), port);\n                using Socket? sock = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);\n                sock.Connect(point);\n                return true;\n            }\n            catch (Exception)\n            {\n                return false;\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/HotkeyHandler.cs",
    "content": "﻿using System.ComponentModel;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Input;\nusing System.Windows.Interop;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    public sealed class HotkeyHandler\n    {\n        private static readonly Lazy<HotkeyHandler> _instance = new(() => new());\n        public static HotkeyHandler Instance = _instance.Value;\n\n        private const int WmHotkey = 0x0312;\n\n        private Config _config\n        {\n            get => LazyConfig.Instance.GetConfig();\n        }\n\n        private Dictionary<int, List<EGlobalHotkey>> _hotkeyTriggerDic;\n\n        public bool IsPause { get; set; } = false;\n\n        public event Action<bool, string>? UpdateViewEvent;\n\n        public event Action<EGlobalHotkey>? HotkeyTriggerEvent;\n\n        public HotkeyHandler()\n        {\n            _hotkeyTriggerDic = new();\n            ComponentDispatcher.ThreadPreprocessMessage += OnThreadPreProcessMessage;\n            Init();\n        }\n\n        private void Init()\n        {\n            _hotkeyTriggerDic.Clear();\n            if (_config.globalHotkeys == null) return;\n            foreach (var item in _config.globalHotkeys)\n            {\n                if (item.KeyCode != null && item.KeyCode != Key.None)\n                {\n                    int key = KeyInterop.VirtualKeyFromKey((Key)item.KeyCode);\n                    KeyModifiers modifiers = KeyModifiers.None;\n                    if (item.Control) modifiers |= KeyModifiers.Ctrl;\n                    if (item.Shift) modifiers |= KeyModifiers.Shift;\n                    if (item.Alt) modifiers |= KeyModifiers.Alt;\n                    key = (key << 16) | (int)modifiers;\n                    if (!_hotkeyTriggerDic.ContainsKey(key))\n                    {\n                        _hotkeyTriggerDic.Add(key, new() { item.eGlobalHotkey });\n                    }\n                    else\n                    {\n                        if (!_hotkeyTriggerDic[key].Contains(item.eGlobalHotkey))\n                            _hotkeyTriggerDic[key].Add(item.eGlobalHotkey);\n                    }\n                }\n            }\n        }\n\n        public void Load()\n        {\n            foreach (var _hotkeyCode in _hotkeyTriggerDic.Keys)\n            {\n                var hotkeyInfo = GetHotkeyInfo(_hotkeyCode);\n                bool isSuccess = false;\n                string msg;\n\n                Application.Current.Dispatcher.Invoke(() =>\n                {\n                    isSuccess = RegisterHotKey(IntPtr.Zero, _hotkeyCode, hotkeyInfo.fsModifiers, hotkeyInfo.vKey);\n                });\n                foreach (var name in hotkeyInfo.Names)\n                {\n                    if (isSuccess)\n                    {\n                        msg = string.Format(ResUI.RegisterGlobalHotkeySuccessfully, $\"{name}({hotkeyInfo.hotkeyStr})\");\n                    }\n                    else\n                    {\n                        var errInfo = new Win32Exception(Marshal.GetLastWin32Error()).Message;\n                        msg = string.Format(ResUI.RegisterGlobalHotkeyFailed, $\"{name}({hotkeyInfo.hotkeyStr})\", errInfo);\n                    }\n                    UpdateViewEvent?.Invoke(false, msg);\n                }\n            }\n        }\n\n        public void ReLoad()\n        {\n            foreach (var hotkey in _hotkeyTriggerDic.Keys)\n            {\n                Application.Current.Dispatcher.Invoke(() =>\n                {\n                    UnregisterHotKey(IntPtr.Zero, hotkey);\n                });\n            }\n            Init();\n            Load();\n        }\n\n        private (int fsModifiers, int vKey, string hotkeyStr, List<string> Names) GetHotkeyInfo(int hotkeycode)\n        {\n            var _fsModifiers = hotkeycode & 0xffff;\n            var _vkey = (hotkeycode >> 16) & 0xffff;\n            var _hotkeyStr = new StringBuilder();\n            var _names = new List<string>();\n\n            var mdif = (KeyModifiers)_fsModifiers;\n            var key = KeyInterop.KeyFromVirtualKey(_vkey);\n            if ((mdif | KeyModifiers.Ctrl) == KeyModifiers.Ctrl) _hotkeyStr.Append($\"{KeyModifiers.Ctrl}+\");\n            if ((mdif | KeyModifiers.Alt) == KeyModifiers.Alt) _hotkeyStr.Append($\"{KeyModifiers.Alt}+\");\n            if ((mdif | KeyModifiers.Shift) == KeyModifiers.Shift) _hotkeyStr.Append($\"{KeyModifiers.Shift}+\");\n            _hotkeyStr.Append(key.ToString());\n\n            foreach (var name in _hotkeyTriggerDic[hotkeycode])\n            {\n                _names.Add(name.ToString());\n            }\n\n            return (_fsModifiers, _vkey, _hotkeyStr.ToString(), _names);\n        }\n\n        private void OnThreadPreProcessMessage(ref MSG msg, ref bool handled)\n        {\n            if (msg.message != WmHotkey || !_hotkeyTriggerDic.ContainsKey((int)msg.lParam))\n            {\n                return;\n            }\n            handled = true;\n            var _hotKeyCode = (int)msg.lParam;\n            if (IsPause)\n            {\n                Application.Current.Dispatcher.Invoke(() =>\n                {\n                    UIElement? element = Keyboard.FocusedElement as UIElement;\n                    if (element != null)\n                    {\n                        var _keyEventArgs = new KeyEventArgs(Keyboard.PrimaryDevice,\n                            PresentationSource.FromVisual(element), 0,\n                            KeyInterop.KeyFromVirtualKey(GetHotkeyInfo(_hotKeyCode).vKey))\n                        {\n                            RoutedEvent = UIElement.KeyDownEvent\n                        };\n                        element.RaiseEvent(_keyEventArgs);\n                    }\n                });\n            }\n            else\n            {\n                foreach (var keyEvent in _hotkeyTriggerDic[(int)msg.lParam])\n                {\n                    HotkeyTriggerEvent?.Invoke(keyEvent);\n                }\n            }\n        }\n\n        [DllImport(\"user32.dll\", SetLastError = true)]\n        private static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vlc);\n\n        [DllImport(\"user32.dll\", SetLastError = true)]\n        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);\n\n        [Flags]\n        private enum KeyModifiers\n        {\n            None = 0x0000,\n            Alt = 0x0001,\n            Ctrl = 0x0002,\n            Shift = 0x0004,\n            Win = 0x0008,\n            NoRepeat = 0x4000\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/LazyConfig.cs",
    "content": "﻿using v2rayN.Base;\nusing v2rayN.Mode;\n\nnamespace v2rayN.Handler\n{\n    public sealed class LazyConfig\n    {\n        private static readonly Lazy<LazyConfig> _instance = new(() => new());\n        private Config _config;\n        private List<CoreInfo> coreInfos;\n\n        public static LazyConfig Instance => _instance.Value;\n\n        public LazyConfig()\n        {\n            SqliteHelper.Instance.CreateTable<SubItem>();\n            SqliteHelper.Instance.CreateTable<ProfileItem>();\n            SqliteHelper.Instance.CreateTable<ServerStatItem>();\n            SqliteHelper.Instance.CreateTable<RoutingItem>();\n            SqliteHelper.Instance.CreateTable<ProfileExItem>();\n            SqliteHelper.Instance.CreateTable<DNSItem>();\n        }\n\n        #region Config\n\n        public void SetConfig(Config config)\n        {\n            _config = config;\n        }\n\n        public Config GetConfig()\n        {\n            return _config;\n        }\n\n        public int GetLocalPort(string protocol)\n        {\n            int localPort = _config.inbound.FirstOrDefault(t => t.protocol == Global.InboundSocks).localPort;\n            if (protocol == Global.InboundSocks)\n            {\n                return localPort;\n            }\n            else if (protocol == Global.InboundHttp)\n            {\n                return localPort + 1;\n            }\n            else if (protocol == Global.InboundSocks2)\n            {\n                return localPort + 2;\n            }\n            else if (protocol == Global.InboundHttp2)\n            {\n                return localPort + 3;\n            }\n            else if (protocol == ESysProxyType.Pac.ToString())\n            {\n                return localPort + 4;\n            }\n            else if (protocol == \"speedtest\")\n            {\n                return localPort + 103;\n            }\n            return localPort;\n        }\n\n        public List<SubItem> SubItems()\n        {\n            return SqliteHelper.Instance.Table<SubItem>().ToList();\n        }\n        public SubItem? GetLastSubItem()\n        {\n            IList<SubItem> subItems = SubItems();\n            if (subItems.Count > 0)\n            {\n                int latestSortNumber = subItems.Max(t => t == null ? 0 : t.sort);\n                SubItem latestAddedSubItem = subItems.First(item => item.sort == latestSortNumber);\n                return latestAddedSubItem;\n            }\n            return null;\n        }\n        public int GetLastSubItemSortNumber()\n        {\n            var lastSortNumber = 0;\n            if (SqliteHelper.Instance.Table<SubItem>().Count() > 0)\n            {\n                lastSortNumber = SqliteHelper.Instance.Table<SubItem>().Max(t => t == null ? 0 : t.sort);\n            }\n            return lastSortNumber;\n        }\n        public SubItem GetSubItem(string subid)\n        {\n            return SqliteHelper.Instance.Table<SubItem>().FirstOrDefault(t => t.id == subid);\n        }\n\n        public List<ProfileItem> ProfileItems(string subid)\n        {\n            if (Utils.IsNullOrEmpty(subid))\n            {\n                return SqliteHelper.Instance.Table<ProfileItem>().ToList();\n            }\n            else\n            {\n                return SqliteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).ToList();\n            }\n        }\n\n        public List<string> ProfileItemIndexs(string subid)\n        {\n            if (Utils.IsNullOrEmpty(subid))\n            {\n                return SqliteHelper.Instance.Table<ProfileItem>().Select(t => t.indexId).ToList();\n            }\n            else\n            {\n                return SqliteHelper.Instance.Table<ProfileItem>().Where(t => t.subid == subid).Select(t => t.indexId).ToList();\n            }\n        }\n\n        public List<ProfileItemModel> ProfileItems(string subid, string filter)\n        {\n            var sql = @$\"select a.*\n                           ,b.remarks subRemarks\n                        from ProfileItem a\n                        left join SubItem b on a.subid = b.id\n                        where 1=1 \";\n            if (!Utils.IsNullOrEmpty(subid))\n            {\n                sql += $\" and a.subid = '{subid}'\";\n            }\n            if (!Utils.IsNullOrEmpty(filter))\n            {\n                if (filter.Contains('\\''))\n                {\n                    filter = filter.Replace(\"'\", \"\");\n                }\n                sql += String.Format(\" and (a.remarks like '%{0}%' or a.address like '%{0}%') \", filter);\n            }\n\n            return SqliteHelper.Instance.Query<ProfileItemModel>(sql).ToList();\n        }\n\n        public ProfileItem? GetProfileItem(string indexId)\n        {\n            if (Utils.IsNullOrEmpty(indexId))\n            {\n                return null;\n            }\n            return SqliteHelper.Instance.Table<ProfileItem>().FirstOrDefault(it => it.indexId == indexId);\n        }\n\n        public List<RoutingItem> RoutingItems()\n        {\n            return SqliteHelper.Instance.Table<RoutingItem>().Where(it => it.locked == false).OrderBy(t => t.sort).ToList();\n        }\n\n        public RoutingItem GetRoutingItem(string id)\n        {\n            return SqliteHelper.Instance.Table<RoutingItem>().FirstOrDefault(it => it.locked == false && it.id == id);\n        }\n\n        public List<DNSItem> DNSItems()\n        {\n            return SqliteHelper.Instance.Table<DNSItem>().ToList();\n        }\n\n        public DNSItem GetDNSItem(ECoreType eCoreType)\n        {\n            return SqliteHelper.Instance.Table<DNSItem>().FirstOrDefault(it => it.coreType == eCoreType);\n        }\n\n        #endregion Config\n\n        #region Core Type\n\n        public List<string> GetShadowsocksSecuritys(ProfileItem profileItem)\n        {\n            if (GetCoreType(profileItem, EConfigType.Shadowsocks) == ECoreType.v2fly)\n            {\n                return Global.ssSecuritys;\n            }\n            if (GetCoreType(profileItem, EConfigType.Shadowsocks) == ECoreType.Xray)\n            {\n                return Global.ssSecuritysInXray;\n            }\n\n            return Global.ssSecuritysInSagerNet;\n        }\n\n        public ECoreType GetCoreType(ProfileItem profileItem, EConfigType eConfigType)\n        {\n            if (profileItem?.coreType != null)\n            {\n                return (ECoreType)profileItem.coreType;\n            }\n\n            if (_config.coreTypeItem == null)\n            {\n                return ECoreType.Xray;\n            }\n            var item = _config.coreTypeItem.FirstOrDefault(it => it.configType == eConfigType);\n            if (item == null)\n            {\n                return ECoreType.Xray;\n            }\n            return item.coreType;\n        }\n\n        public CoreInfo? GetCoreInfo(ECoreType coreType)\n        {\n            if (coreInfos == null)\n            {\n                InitCoreInfo();\n            }\n            return coreInfos!.FirstOrDefault(t => t.coreType == coreType);\n        }\n\n        public List<CoreInfo>? GetCoreInfos()\n        {\n            if (coreInfos == null)\n            {\n                InitCoreInfo();\n            }\n            return coreInfos;\n        }\n\n        private void InitCoreInfo()\n        {\n            coreInfos = new(16);\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.v2rayN,\n                coreUrl = Global.NUrl,\n                coreReleaseApiUrl = Global.NUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.NUrl + \"/download/{0}/v2rayN-32.zip\",\n                coreDownloadUrl64 = Global.NUrl + \"/download/{0}/v2rayN.zip\",\n                coreDownloadUrlArm64 = Global.NUrl + \"/download/{0}/v2rayN-arm64.zip\"\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.v2fly,\n                coreExes = new List<string> { \"wv2ray\", \"v2ray\" },\n                arguments = \"\",\n                coreUrl = Global.v2flyCoreUrl,\n                coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.v2flyCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                coreDownloadUrl64 = Global.v2flyCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                coreDownloadUrlArm64 = Global.v2flyCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                match = \"V2Ray\",\n                versionArg = \"-version\",\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.SagerNet,\n                coreExes = new List<string> { \"SagerNet\", \"v2ray\" },\n                arguments = \"run\",\n                coreUrl = Global.SagerNetCoreUrl,\n                coreReleaseApiUrl = Global.SagerNetCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.SagerNetCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                coreDownloadUrl64 = Global.SagerNetCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                coreDownloadUrlArm64 = Global.SagerNetCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                match = \"V2Ray\",\n                versionArg = \"version\",\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.v2fly_v5,\n                coreExes = new List<string> { \"v2ray\" },\n                arguments = \"run\",\n                coreUrl = Global.v2flyCoreUrl,\n                coreReleaseApiUrl = Global.v2flyCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.v2flyCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                coreDownloadUrl64 = Global.v2flyCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                coreDownloadUrlArm64 = Global.v2flyCoreUrl + \"/download/{0}/v2ray-windows-{1}.zip\",\n                match = \"V2Ray\",\n                versionArg = \"version\",\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.Xray,\n                coreExes = new List<string> { \"xray\", \"wxray\" },\n                arguments = \"\",\n                coreUrl = Global.xrayCoreUrl,\n                coreReleaseApiUrl = Global.xrayCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.xrayCoreUrl + \"/download/{0}/Xray-windows-{1}.zip\",\n                coreDownloadUrl64 = Global.xrayCoreUrl + \"/download/{0}/Xray-windows-{1}.zip\",\n                coreDownloadUrlArm64 = Global.xrayCoreUrl + \"/download/{0}/Xray-windows-{1}.zip\",\n                match = \"Xray\",\n                versionArg = \"-version\",\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.clash,\n                coreExes = new List<string> { \"clash-windows-amd64-v3\", \"clash-windows-amd64\", \"clash-windows-386\", \"clash\" },\n                arguments = \"-f config.json\",\n                coreUrl = Global.clashCoreUrl,\n                coreReleaseApiUrl = Global.clashCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.clashCoreUrl + \"/download/{0}/clash-windows-386-{0}.zip\",\n                coreDownloadUrl64 = Global.clashCoreUrl + \"/download/{0}/clash-windows-amd64-{0}.zip\",\n                coreDownloadUrlArm64 = Global.clashCoreUrl + \"/download/{0}/clash-windows-arm64-{0}.zip\",\n                match = \"v\",\n                versionArg = \"-v\",\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.clash_meta,\n                coreExes = new List<string> { \"Clash.Meta-windows-amd64-compatible\", \"Clash.Meta-windows-amd64\", \"Clash.Meta-windows-386\", \"Clash.Meta\", \"clash\" },\n                arguments = \"-f config.json\",\n                coreUrl = Global.clashMetaCoreUrl,\n                coreReleaseApiUrl = Global.clashMetaCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.clashMetaCoreUrl + \"/download/{0}/Clash.Meta-windows-386-{0}.zip\",\n                coreDownloadUrl64 = Global.clashMetaCoreUrl + \"/download/{0}/Clash.Meta-windows-amd64-compatible-{0}.zip\",\n                coreDownloadUrlArm64 = Global.clashMetaCoreUrl + \"/download/{0}/Clash.Meta-windows-arm64-{0}.zip\",\n                match = \"v\",\n                versionArg = \"-v\",\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.hysteria,\n                coreExes = new List<string> { \"hysteria-windows-amd64\", \"hysteria-windows-386\", \"hysteria\" },\n                arguments = \"\",\n                coreUrl = Global.hysteriaCoreUrl,\n                coreReleaseApiUrl = Global.hysteriaCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.hysteriaCoreUrl + \"/download/{0}/hysteria-windows-386.exe\",\n                coreDownloadUrl64 = Global.hysteriaCoreUrl + \"/download/{0}/hysteria-windows-amd64.exe\",\n                coreDownloadUrlArm64 = Global.hysteriaCoreUrl + \"/download/{0}/hysteria-windows-arm64.exe\",\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.naiveproxy,\n                coreExes = new List<string> { \"naiveproxy\", \"naive\" },\n                arguments = \"config.json\",\n                coreUrl = Global.naiveproxyCoreUrl,\n                redirectInfo = false,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.tuic,\n                coreExes = new List<string> { \"tuic-client\", \"tuic\" },\n                arguments = \"-c config.json\",\n                coreUrl = Global.tuicCoreUrl,\n                redirectInfo = true,\n            });\n\n            coreInfos.Add(new CoreInfo\n            {\n                coreType = ECoreType.sing_box,\n                coreExes = new List<string> { \"sing-box-client\", \"sing-box\" },\n                arguments = \"run{0}\",\n                coreUrl = Global.singboxCoreUrl,\n                redirectInfo = true,\n                coreReleaseApiUrl = Global.singboxCoreUrl.Replace(Global.githubUrl, Global.githubApiUrl),\n                coreDownloadUrl32 = Global.singboxCoreUrl + \"/download/{0}/sing-box-{1}-windows-386.zip\",\n                coreDownloadUrl64 = Global.singboxCoreUrl + \"/download/{0}/sing-box-{1}-windows-amd64.zip\",\n                coreDownloadUrlArm64 = Global.singboxCoreUrl + \"/download/{0}/sing-box-{1}-windows-arm64.zip\",\n                match = \"sing-box\",\n                versionArg = \"version\",\n            });\n        }\n\n        #endregion Core Type\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/MainFormHandler.cs",
    "content": "﻿using Microsoft.Win32;\nusing System.Drawing;\nusing System.IO;\nusing System.Windows.Media.Imaging;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    public sealed class MainFormHandler\n    {\n        private static readonly Lazy<MainFormHandler> instance = new(() => new());\n        public static MainFormHandler Instance => instance.Value;\n\n        public Icon GetNotifyIcon(Config config)\n        {\n            try\n            {\n                int index = (int)config.sysProxyType;\n\n                //Load from routing setting\n                var createdIcon = GetNotifyIcon4Routing(config);\n                if (createdIcon != null)\n                {\n                    return createdIcon;\n                }\n\n                //Load from local file\n                var fileName = Utils.GetPath($\"NotifyIcon{index + 1}.ico\");\n                if (File.Exists(fileName))\n                {\n                    return new Icon(fileName);\n                }\n                return index switch\n                {\n                    0 => Properties.Resources.NotifyIcon1,\n                    1 => Properties.Resources.NotifyIcon2,\n                    2 => Properties.Resources.NotifyIcon3,\n                    3 => Properties.Resources.NotifyIcon2,\n                    _ => Properties.Resources.NotifyIcon1, // default\n                };\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                return Properties.Resources.NotifyIcon1;\n            }\n        }\n\n        public System.Windows.Media.ImageSource GetAppIcon(Config config)\n        {\n            int index = 1;\n            switch ((int)config.sysProxyType)\n            {\n                case 0:\n                    index = 1;\n                    break;\n\n                case 1:\n                case 3:\n                    index = 2;\n                    break;\n\n                case 2:\n                    index = 3;\n                    break;\n            }\n            return BitmapFrame.Create(new Uri($\"pack://application:,,,/Resources/NotifyIcon{index}.ico\", UriKind.RelativeOrAbsolute));\n        }\n\n        private Icon? GetNotifyIcon4Routing(Config config)\n        {\n            try\n            {\n                if (!config.routingBasicItem.enableRoutingAdvanced)\n                {\n                    return null;\n                }\n\n                var item = ConfigHandler.GetDefaultRouting(ref config);\n                if (item == null || Utils.IsNullOrEmpty(item.customIcon) || !File.Exists(item.customIcon))\n                {\n                    return null;\n                }\n\n                Color color = ColorTranslator.FromHtml(\"#3399CC\");\n                int index = (int)config.sysProxyType;\n                if (index > 0)\n                {\n                    color = (new[] { Color.Red, Color.Purple, Color.DarkGreen, Color.Orange, Color.DarkSlateBlue, Color.RoyalBlue })[index - 1];\n                }\n\n                int width = 128;\n                int height = 128;\n\n                Bitmap bitmap = new(width, height);\n                Graphics graphics = Graphics.FromImage(bitmap);\n                SolidBrush drawBrush = new(color);\n\n                graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;\n                //graphics.FillRectangle(drawBrush, new Rectangle(0, 0, width, height));\n                graphics.DrawImage(new Bitmap(item.customIcon), 0, 0, width, height);\n                graphics.FillEllipse(drawBrush, width / 2, width / 2, width / 2, width / 2);\n\n                Icon createdIcon = Icon.FromHandle(bitmap.GetHicon());\n\n                drawBrush.Dispose();\n                graphics.Dispose();\n                bitmap.Dispose();\n\n                return createdIcon;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                return null;\n            }\n        }\n\n        public void Export2ClientConfig(ProfileItem item, Config config)\n        {\n            if (item == null)\n            {\n                return;\n            }\n            if (item.configType == EConfigType.Custom)\n            {\n                UI.Show(ResUI.NonVmessService);\n                return;\n            }\n\n            SaveFileDialog fileDialog = new()\n            {\n                Filter = \"Config|*.json\",\n                FilterIndex = 2,\n                RestoreDirectory = true\n            };\n            if (fileDialog.ShowDialog() != true)\n            {\n                return;\n            }\n            string fileName = fileDialog.FileName;\n            if (Utils.IsNullOrEmpty(fileName))\n            {\n                return;\n            }\n            if (CoreConfigHandler.GenerateClientConfig(item, fileName, out string msg, out string content) != 0)\n            {\n                UI.Show(msg);\n            }\n            else\n            {\n                UI.ShowWarning(string.Format(ResUI.SaveClientConfigurationIn, fileName));\n            }\n        }\n\n        public void UpdateTask(Config config, Action<bool, string> update)\n        {\n            // We don't want to update subscription manually in code, it'll be handled in another part of code (search Auto update sub)\n            //Task.Run(() => UpdateTaskRunSubscription(config, update));\n            Task.Run(() => UpdateTaskRunGeo(config, update));\n        }\n\n        private void UpdateTaskRunSubscription(Config config, Action<bool, string> update)\n        {\n            Thread.Sleep(60000);\n            Utils.SaveLog(\"UpdateTaskRunSubscription\");\n\n            var updateHandle = new UpdateHandle();\n            while (true)\n            {\n                var updateTime = ((DateTimeOffset)DateTime.Now).ToUnixTimeSeconds();\n                var lstSubs = LazyConfig.Instance.SubItems()\n                            .Where(t => t.profileUpdateInterval > 0)\n                            .Where(t => updateTime - t.updateTime >= t.profileUpdateInterval * 60)\n                            .ToList();\n\n                foreach (var item in lstSubs)\n                {\n                    updateHandle.UpdateSubscriptionProcess(config, item.id, true, (bool success, string msg) =>\n                    {\n                        update(success, msg);\n                        if (success)\n                            Utils.SaveLog(\"subscription\" + msg);\n                    });\n                    item.updateTime = updateTime;\n                    ConfigHandler.AddSubItem(ref config, item);\n\n                    Thread.Sleep(5000);\n                }\n                Thread.Sleep(60000);\n            }\n        }\n\n        private void UpdateTaskRunGeo(Config config, Action<bool, string> update)\n        {\n            var autoUpdateGeoTime = DateTime.Now;\n\n            Thread.Sleep(1000 * 120);\n            Utils.SaveLog(\"UpdateTaskRunGeo\");\n\n            var updateHandle = new UpdateHandle();\n            while (true)\n            {\n                var dtNow = DateTime.Now;\n                if (config.guiItem.autoUpdateInterval > 0)\n                {\n                    if ((dtNow - autoUpdateGeoTime).Hours % config.guiItem.autoUpdateInterval == 0)\n                    {\n                        updateHandle.UpdateGeoFileAll(config, (bool success, string msg) =>\n                        {\n                            update(false, msg);                          \n                        });                      \n                        autoUpdateGeoTime = dtNow;\n                    }\n                }\n\n                Thread.Sleep(1000 * 3600);\n            }\n        }\n\n        public void RegisterGlobalHotkey(Config config, Action<EGlobalHotkey> handler, Action<bool, string> update)\n        {\n            HotkeyHandler.Instance.UpdateViewEvent += update;\n            HotkeyHandler.Instance.HotkeyTriggerEvent += handler;\n            HotkeyHandler.Instance.Load();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/NoticeHandler.cs",
    "content": "﻿using MaterialDesignThemes.Wpf;\nusing ReactiveUI;\n\nnamespace v2rayN.Handler\n{\n    public class NoticeHandler\n    {\n        private readonly ISnackbarMessageQueue _snackbarMessageQueue;\n\n        public NoticeHandler(ISnackbarMessageQueue snackbarMessageQueue)\n        {\n            _snackbarMessageQueue = snackbarMessageQueue ?? throw new ArgumentNullException(nameof(snackbarMessageQueue));\n\n            //_snackbarMessageQueue = snackbarMessageQueue;\n        }\n\n        public void Enqueue(object content)\n        {\n            _snackbarMessageQueue?.Enqueue(content);\n        }\n\n        public void SendMessage(string msg)\n        {\n            MessageBus.Current.SendMessage(msg, \"MsgView\");\n        }\n\n        public void SendMessage(string msg, bool time)\n        {\n            msg = $\"{DateTime.Now} {msg}\";\n            MessageBus.Current.SendMessage(msg, \"MsgView\");\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/ProfileExHandler.cs",
    "content": "﻿using System.Collections.Concurrent;\nusing System.Reactive.Linq;\nusing v2rayN.Base;\nusing v2rayN.Mode;\n\nnamespace v2rayN.Handler\n{\n    internal class ProfileExHandler\n    {\n        private static readonly Lazy<ProfileExHandler> _instance = new(() => new());\n        private ConcurrentBag<ProfileExItem> _lstProfileEx;\n        private Queue<string> _queIndexIds = new();\n        public ConcurrentBag<ProfileExItem> ProfileExs => _lstProfileEx;\n        public static ProfileExHandler Instance => _instance.Value;\n\n        public ProfileExHandler()\n        {\n            Init();\n        }\n\n        private void Init()\n        {\n            SqliteHelper.Instance.Execute($\"delete from ProfileExItem where indexId not in ( select indexId from ProfileItem )\");\n\n            _lstProfileEx = new(SqliteHelper.Instance.Table<ProfileExItem>());\n\n            Task.Run(() =>\n            {\n                while (true)\n                {\n                    var cnt = _queIndexIds.Count;\n                    for (int i = 0; i < cnt; i++)\n                    {\n                        var id = _queIndexIds.Dequeue();\n                        var item = _lstProfileEx.FirstOrDefault(t => t.indexId == id);\n                        if (item is not null)\n                        {\n                            SqliteHelper.Instance.Replace(item);\n                        }\n                    }\n                    Thread.Sleep(1000 * 60);\n                }\n            });\n        }\n\n        private void IndexIdEnqueue(string indexId)\n        {\n            if (!Utils.IsNullOrEmpty(indexId) && !_queIndexIds.Contains(indexId))\n            {\n                _queIndexIds.Enqueue(indexId);\n            }\n        }\n\n        private void AddProfileEx(string indexId, ref ProfileExItem profileEx)\n        {\n            profileEx = new()\n            {\n                indexId = indexId,\n                delay = 0,\n                speed = 0,\n                sort = 0\n            };\n            _lstProfileEx.Add(profileEx);\n            IndexIdEnqueue(indexId);\n        }\n\n        public void ClearAll()\n        {\n            SqliteHelper.Instance.Execute($\"delete from ProfileExItem \");\n            _lstProfileEx = new();\n        }\n\n        public void SaveTo()\n        {\n            try\n            {\n                //foreach (var item in _lstProfileEx)\n                //{\n                //    SqliteHelper.Instance.Replace(item);\n                //}\n                SqliteHelper.Instance.UpdateAll(_lstProfileEx);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        public void SetTestDelay(string indexId, string delayVal)\n        {\n            var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId);\n            if (profileEx == null)\n            {\n                AddProfileEx(indexId, ref profileEx);\n            }\n\n            int.TryParse(delayVal, out int delay);\n            profileEx.delay = delay;\n            IndexIdEnqueue(indexId);\n        }\n\n        public void SetTestSpeed(string indexId, string speedVal)\n        {\n            var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId);\n            if (profileEx == null)\n            {\n                AddProfileEx(indexId, ref profileEx);\n            }\n\n            decimal.TryParse(speedVal, out decimal speed);\n            profileEx.speed = speed;\n            IndexIdEnqueue(indexId);\n        }\n\n        public void SetSort(string indexId, int sort)\n        {\n            var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId);\n            if (profileEx == null)\n            {\n                AddProfileEx(indexId, ref profileEx);\n            }\n            profileEx.sort = sort;\n            IndexIdEnqueue(indexId);\n        }\n\n        public int GetSort(string indexId)\n        {\n            var profileEx = _lstProfileEx.FirstOrDefault(t => t.indexId == indexId);\n            if (profileEx == null)\n            {\n                return 0;\n            }\n            return profileEx.sort;\n        }\n\n        public int GetMaxSort()\n        {\n            if (_lstProfileEx.Count <= 0)\n            {\n                return 0;\n            }\n            return _lstProfileEx.Max(t => t == null ? 0 : t.sort);\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/ProxySetting.cs",
    "content": "﻿using Microsoft.Win32;\nusing System.Runtime.InteropServices;\n\nnamespace v2rayN.Handler\n{\n    internal class ProxySetting\n    {\n        public static bool UnsetProxy()\n        {\n            return SetProxy(null, null, 1);\n        }\n\n        public static bool SetProxy(string? strProxy, string? exceptions, int type)\n        {\n            InternetPerConnOptionList list = new();\n\n            int optionCount = 1;\n            if (type == 1)\n            {\n                optionCount = 1;\n            }\n            else if (type is 2 or 4)\n            {\n                optionCount = Utils.IsNullOrEmpty(exceptions) ? 2 : 3;\n            }\n\n            int m_Int = (int)PerConnFlags.PROXY_TYPE_DIRECT;\n            PerConnOption m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;\n            if (type == 2)\n            {\n                m_Int = (int)(PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY);\n                m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_SERVER;\n            }\n            else if (type == 4)\n            {\n                m_Int = (int)(PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_AUTO_PROXY_URL);\n                m_Option = PerConnOption.INTERNET_PER_CONN_AUTOCONFIG_URL;\n            }\n\n            //int optionCount = Utils.IsNullOrEmpty(strProxy) ? 1 : (Utils.IsNullOrEmpty(exceptions) ? 2 : 3);\n            InternetConnectionOption[] options = new InternetConnectionOption[optionCount];\n            // USE a proxy server ...\n            options[0].m_Option = PerConnOption.INTERNET_PER_CONN_FLAGS;\n            //options[0].m_Value.m_Int = (int)((optionCount < 2) ? PerConnFlags.PROXY_TYPE_DIRECT : (PerConnFlags.PROXY_TYPE_DIRECT | PerConnFlags.PROXY_TYPE_PROXY));\n            options[0].m_Value.m_Int = m_Int;\n            // use THIS proxy server\n            if (optionCount > 1)\n            {\n                options[1].m_Option = m_Option;\n                options[1].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(strProxy);\n                // except for these addresses ...\n                if (optionCount > 2)\n                {\n                    options[2].m_Option = PerConnOption.INTERNET_PER_CONN_PROXY_BYPASS;\n                    options[2].m_Value.m_StringPtr = Marshal.StringToHGlobalAuto(exceptions);\n                }\n            }\n\n            // default stuff\n            list.dwSize = Marshal.SizeOf(list);\n            list.szConnection = IntPtr.Zero;\n            list.dwOptionCount = options.Length;\n            list.dwOptionError = 0;\n\n            int optSize = Marshal.SizeOf(typeof(InternetConnectionOption));\n            // make a pointer out of all that ...\n            IntPtr optionsPtr = Marshal.AllocCoTaskMem(optSize * options.Length);\n            // copy the array over into that spot in memory ...\n            for (int i = 0; i < options.Length; ++i)\n            {\n                if (Environment.Is64BitOperatingSystem)\n                {\n                    IntPtr opt = new(optionsPtr.ToInt64() + (i * optSize));\n                    Marshal.StructureToPtr(options[i], opt, false);\n                }\n                else\n                {\n                    IntPtr opt = new(optionsPtr.ToInt32() + (i * optSize));\n                    Marshal.StructureToPtr(options[i], opt, false);\n                }\n            }\n\n            list.options = optionsPtr;\n\n            // and then make a pointer out of the whole list\n            IntPtr ipcoListPtr = Marshal.AllocCoTaskMem(list.dwSize);\n            Marshal.StructureToPtr(list, ipcoListPtr, false);\n\n            // and finally, call the API method!\n            int returnvalue = NativeMethods.InternetSetOption(IntPtr.Zero,\n               InternetOption.INTERNET_OPTION_PER_CONNECTION_OPTION,\n               ipcoListPtr, list.dwSize) ? -1 : 0;\n            if (returnvalue == 0)\n            {  // get the error codes, they might be helpful\n                returnvalue = Marshal.GetLastWin32Error();\n            }\n            // FREE the data ASAP\n            Marshal.FreeCoTaskMem(optionsPtr);\n            Marshal.FreeCoTaskMem(ipcoListPtr);\n            if (returnvalue > 0)\n            {  // throw the error codes, they might be helpful\n                //throw new Win32Exception(Marshal.GetLastWin32Error());\n            }\n\n            return (returnvalue < 0);\n        }\n\n        #region WinInet structures\n\n        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\n        public struct InternetPerConnOptionList\n        {\n            public int dwSize;               // size of the INTERNET_PER_CONN_OPTION_LIST struct\n            public IntPtr szConnection;         // connection name to set/query options\n            public int dwOptionCount;        // number of options to set/query\n            public int dwOptionError;           // on error, which option failed\n\n            //[MarshalAs(UnmanagedType.)]\n            public IntPtr options;\n        };\n\n        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]\n        public struct InternetConnectionOption\n        {\n            private static readonly int Size;\n            public PerConnOption m_Option;\n            public InternetConnectionOptionValue m_Value;\n\n            static InternetConnectionOption()\n            {\n                Size = Marshal.SizeOf(typeof(InternetConnectionOption));\n            }\n\n            // Nested Types\n            [StructLayout(LayoutKind.Explicit)]\n            public struct InternetConnectionOptionValue\n            {\n                // Fields\n                [FieldOffset(0)]\n                public System.Runtime.InteropServices.ComTypes.FILETIME m_FileTime;\n\n                [FieldOffset(0)]\n                public int m_Int;\n\n                [FieldOffset(0)]\n                public IntPtr m_StringPtr;\n            }\n        }\n\n        #endregion WinInet structures\n\n        #region WinInet enums\n\n        //\n        // options manifests for Internet{Query|Set}Option\n        //\n        public enum InternetOption : uint\n        {\n            INTERNET_OPTION_PER_CONNECTION_OPTION = 75\n        }\n\n        //\n        // Options used in INTERNET_PER_CONN_OPTON struct\n        //\n        public enum PerConnOption\n        {\n            INTERNET_PER_CONN_FLAGS = 1, // Sets or retrieves the connection type. The Value member will contain one or more of the values from PerConnFlags\n            INTERNET_PER_CONN_PROXY_SERVER = 2, // Sets or retrieves a string containing the proxy servers.\n            INTERNET_PER_CONN_PROXY_BYPASS = 3, // Sets or retrieves a string containing the URLs that do not use the proxy server.\n            INTERNET_PER_CONN_AUTOCONFIG_URL = 4//, // Sets or retrieves a string containing the URL to the automatic configuration script.\n        }\n\n        //\n        // PER_CONN_FLAGS\n        //\n        [Flags]\n        public enum PerConnFlags\n        {\n            PROXY_TYPE_DIRECT = 0x00000001,  // direct to net\n            PROXY_TYPE_PROXY = 0x00000002,  // via named proxy\n            PROXY_TYPE_AUTO_PROXY_URL = 0x00000004,  // autoproxy URL\n            PROXY_TYPE_AUTO_DETECT = 0x00000008   // use autoproxy detection\n        }\n\n        #endregion WinInet enums\n\n        internal static class NativeMethods\n        {\n            [DllImport(\"WinInet.dll\", SetLastError = true, CharSet = CharSet.Auto)]\n            [return: MarshalAs(UnmanagedType.Bool)]\n            public static extern bool InternetSetOption(IntPtr hInternet, InternetOption dwOption, IntPtr lpBuffer, int dwBufferLength);\n        }\n\n        //判断是否使用代理\n        public static bool UsedProxy()\n        {\n            using RegistryKey? rk = Registry.CurrentUser.OpenSubKey(@\"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\", true);\n            if (rk?.GetValue(\"ProxyEnable\")?.ToString() == \"1\")\n            {\n                return true;\n            }\n            else\n            {\n                return false;\n            }\n        }\n\n        //获得代理的IP和端口\n        public static string? GetProxyProxyServer()\n        {\n            using RegistryKey? rk = Registry.CurrentUser.OpenSubKey(@\"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\", true);\n            string ProxyServer = rk.GetValue(\"ProxyServer\").ToString();\n            return ProxyServer;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/QRCodeHelper.cs",
    "content": "﻿using QRCoder;\nusing QRCoder.Xaml;\nusing System.Windows.Media;\n\nnamespace v2rayN.Handler\n{\n    /// <summary>\n    /// 含有QR码的描述类和包装编码和渲染\n    /// </summary>\n    public class QRCodeHelper\n    {\n        public static DrawingImage? GetQRCode(string strContent)\n        {\n            try\n            {\n                QRCodeGenerator qrGenerator = new();\n                QRCodeData qrCodeData = qrGenerator.CreateQrCode(strContent, QRCodeGenerator.ECCLevel.H);\n                XamlQRCode qrCode = new(qrCodeData);\n                DrawingImage qrCodeAsXaml = qrCode.GetGraphic(40);\n                return qrCodeAsXaml;\n            }\n            catch\n            {\n                return null;\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/ShareHandler.cs",
    "content": "﻿using System.Collections.Specialized;\nusing System.Text.RegularExpressions;\nusing System.Web;\nusing v2rayN.Base;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    internal class ShareHandler\n    {\n        #region GetShareUrl\n\n        /// <summary>\n        /// GetShareUrl\n        /// </summary>\n        /// <param name=\"item\"></param>\n        /// <returns></returns>\n        public static string? GetShareUrl(ProfileItem item)\n        {\n            try\n            {\n                string? url = string.Empty;\n\n                url = item.configType switch\n                {\n                    EConfigType.VMess => ShareVmess(item),\n                    EConfigType.Shadowsocks => ShareShadowsocks(item),\n                    EConfigType.Socks => ShareSocks(item),\n                    EConfigType.Trojan => ShareTrojan(item),\n                    EConfigType.VLESS => ShareVLESS(item),\n                    _ => null,\n                };\n\n                return url;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                return \"\";\n            }\n        }\n\n        private static string ShareVmess(ProfileItem item)\n        {\n            string url = string.Empty;\n\n            VmessQRCode vmessQRCode = new()\n            {\n                v = item.configVersion.ToString(),\n                ps = item.remarks.TrimEx(),\n                add = item.address,\n                port = item.port.ToString(),\n                id = item.id,\n                aid = item.alterId.ToString(),\n                scy = item.security,\n                net = item.network,\n                type = item.headerType,\n                host = item.requestHost,\n                path = item.path,\n                tls = item.streamSecurity,\n                sni = item.sni,\n                alpn = item.alpn,\n                fp = item.fingerprint,\n                allowInsecure = item.allowInsecure\n        };\n\n            url = Utils.ToJson(vmessQRCode);\n            url = Utils.Base64Encode(url);\n            url = $\"{Global.vmessProtocol}{url}\";\n\n            return url;\n        }\n\n        private static string ShareShadowsocks(ProfileItem item)\n        {\n            string url = string.Empty;\n\n            string remark = string.Empty;\n            if (!Utils.IsNullOrEmpty(item.remarks))\n            {\n                remark = \"#\" + Utils.UrlEncode(item.remarks);\n            }\n            //url = string.Format(\"{0}:{1}@{2}:{3}\",\n            //    item.security,\n            //    item.id,\n            //    item.address,\n            //    item.port);\n            //url = Utils.Base64Encode(url);\n            //new Sip002\n            var pw = Utils.Base64Encode($\"{item.security}:{item.id}\");\n            url = $\"{pw}@{GetIpv6(item.address)}:{item.port}\";\n            url = $\"{Global.ssProtocol}{url}{remark}\";\n            return url;\n        }\n\n        private static string ShareSocks(ProfileItem item)\n        {\n            string url = string.Empty;\n            string remark = string.Empty;\n            if (!Utils.IsNullOrEmpty(item.remarks))\n            {\n                remark = \"#\" + Utils.UrlEncode(item.remarks);\n            }\n            //url = string.Format(\"{0}:{1}@{2}:{3}\",\n            //    item.security,\n            //    item.id,\n            //    item.address,\n            //    item.port);\n            //url = Utils.Base64Encode(url);\n            //new\n            var pw = Utils.Base64Encode($\"{item.security}:{item.id}\");\n            url = $\"{pw}@{GetIpv6(item.address)}:{item.port}\";\n            url = $\"{Global.socksProtocol}{url}{remark}\";\n            return url;\n        }\n\n        private static string ShareTrojan(ProfileItem item)\n        {\n            string url = string.Empty;\n            string remark = string.Empty;\n            if (!Utils.IsNullOrEmpty(item.remarks))\n            {\n                remark = \"#\" + Utils.UrlEncode(item.remarks);\n            }\n            var dicQuery = new Dictionary<string, string>();\n            GetStdTransport(item, null, ref dicQuery);\n            string query = \"?\" + string.Join(\"&\", dicQuery.Select(x => x.Key + \"=\" + x.Value).ToArray());\n\n            url = string.Format(\"{0}@{1}:{2}\",\n            item.id,\n            GetIpv6(item.address),\n            item.port);\n            url = $\"{Global.trojanProtocol}{url}{query}{remark}\";\n            return url;\n        }\n\n        private static string ShareVLESS(ProfileItem item)\n        {\n            string url = string.Empty;\n            string remark = string.Empty;\n            if (!Utils.IsNullOrEmpty(item.remarks))\n            {\n                remark = \"#\" + Utils.UrlEncode(item.remarks);\n            }\n            var dicQuery = new Dictionary<string, string>();\n            if (!Utils.IsNullOrEmpty(item.security))\n            {\n                dicQuery.Add(\"encryption\", item.security);\n            }\n            else\n            {\n                dicQuery.Add(\"encryption\", \"none\");\n            }\n            GetStdTransport(item, \"none\", ref dicQuery);\n            string query = \"?\" + string.Join(\"&\", dicQuery.Select(x => x.Key + \"=\" + x.Value).ToArray());\n\n            url = string.Format(\"{0}@{1}:{2}\",\n            item.id,\n            GetIpv6(item.address),\n            item.port);\n            url = $\"{Global.vlessProtocol}{url}{query}{remark}\";\n            return url;\n        }\n\n        private static string GetIpv6(string address)\n        {\n            return Utils.IsIpv6(address) ? $\"[{address}]\" : address;\n        }\n\n        private static int GetStdTransport(ProfileItem item, string? securityDef, ref Dictionary<string, string> dicQuery)\n        {\n            if (!Utils.IsNullOrEmpty(item.flow))\n            {\n                dicQuery.Add(\"flow\", item.flow);\n            }\n\n            if (!Utils.IsNullOrEmpty(item.streamSecurity))\n            {\n                dicQuery.Add(\"security\", item.streamSecurity);\n            }\n            else\n            {\n                if (securityDef != null)\n                {\n                    dicQuery.Add(\"security\", securityDef);\n                }\n            }\n            if (!Utils.IsNullOrEmpty(item.sni))\n            {\n                dicQuery.Add(\"sni\", item.sni);\n            }\n            if (!Utils.IsNullOrEmpty(item.alpn))\n            {\n                dicQuery.Add(\"alpn\", Utils.UrlEncode(item.alpn));\n            }\n            if (!Utils.IsNullOrEmpty(item.fingerprint))\n            {\n                dicQuery.Add(\"fp\", Utils.UrlEncode(item.fingerprint));\n            }\n  \t\t\t\n            if (!Utils.IsNullOrEmpty(item.allowInsecure))//Hiddify\n            {\n                dicQuery.Add(\"allowInsecure\", item.allowInsecure);\n            }\n            if (!Utils.IsNullOrEmpty(item.publicKey))\n            {\n                dicQuery.Add(\"pbk\", Utils.UrlEncode(item.publicKey));\n            }\n            if (!Utils.IsNullOrEmpty(item.shortId))\n            {\n                dicQuery.Add(\"sid\", Utils.UrlEncode(item.shortId));\n            }\n            if (!Utils.IsNullOrEmpty(item.spiderX))\n            {\n                dicQuery.Add(\"spx\", Utils.UrlEncode(item.spiderX));\n            }\n\n            dicQuery.Add(\"type\", !Utils.IsNullOrEmpty(item.network) ? item.network : \"tcp\");\n\n            switch (item.network)\n            {\n                case \"tcp\":\n                    dicQuery.Add(\"headerType\", !Utils.IsNullOrEmpty(item.headerType) ? item.headerType : \"none\");\n                    if (!Utils.IsNullOrEmpty(item.requestHost))\n                    {\n                        dicQuery.Add(\"host\", Utils.UrlEncode(item.requestHost));\n                    }\n                    break;\n\n                case \"kcp\":\n                    dicQuery.Add(\"headerType\", !Utils.IsNullOrEmpty(item.headerType) ? item.headerType : \"none\");\n                    if (!Utils.IsNullOrEmpty(item.path))\n                    {\n                        dicQuery.Add(\"seed\", Utils.UrlEncode(item.path));\n                    }\n                    break;\n\n                case \"ws\":\n                    if (!Utils.IsNullOrEmpty(item.requestHost))\n                    {\n                        dicQuery.Add(\"host\", Utils.UrlEncode(item.requestHost));\n                    }\n                    if (!Utils.IsNullOrEmpty(item.path))\n                    {\n                        dicQuery.Add(\"path\", Utils.UrlEncode(item.path));\n                    }\n                    break;\n\n                case \"http\":\n                case \"h2\":\n                    dicQuery[\"type\"] = \"http\";\n                    if (!Utils.IsNullOrEmpty(item.requestHost))\n                    {\n                        dicQuery.Add(\"host\", Utils.UrlEncode(item.requestHost));\n                    }\n                    if (!Utils.IsNullOrEmpty(item.path))\n                    {\n                        dicQuery.Add(\"path\", Utils.UrlEncode(item.path));\n                    }\n                    break;\n\n                case \"quic\":\n                    dicQuery.Add(\"headerType\", !Utils.IsNullOrEmpty(item.headerType) ? item.headerType : \"none\");\n                    dicQuery.Add(\"quicSecurity\", Utils.UrlEncode(item.requestHost));\n                    dicQuery.Add(\"key\", Utils.UrlEncode(item.path));\n                    break;\n\n                case \"grpc\":\n                    if (!Utils.IsNullOrEmpty(item.path))\n                    {\n                        dicQuery.Add(\"serviceName\", Utils.UrlEncode(item.path));\n                        if (item.headerType is Global.GrpcgunMode or Global.GrpcmultiMode)\n                        {\n                            dicQuery.Add(\"mode\", Utils.UrlEncode(item.headerType));\n                        }\n                    }\n                    break;\n            }\n            return 0;\n        }\n\n        #endregion GetShareUrl\n\n        #region ImportShareUrl\n\n        /// <summary>\n        /// 从剪贴板导入URL\n        /// </summary>\n        /// <param name=\"msg\"></param>\n        /// <returns></returns>\n        public static ProfileItem? ImportFromClipboardConfig(string clipboardData, out string msg)\n        {\n            msg = string.Empty;\n\n            ProfileItem profileItem = new();\n\n            try\n            {\n                //载入配置文件\n                string result = clipboardData.TrimEx();// Utils.GetClipboardData();\n                if (Utils.IsNullOrEmpty(result))\n                {\n                    msg = ResUI.FailedReadConfiguration;\n                    return null;\n                }\n\n                if (result.StartsWith(Global.vmessProtocol))\n                {\n                    int indexSplit = result.IndexOf(\"?\");\n                    if (indexSplit > 0)\n                    {\n                        profileItem = ResolveStdVmess(result) ?? ResolveVmess4Kitsunebi(result);\n                    }\n                    else\n                    {\n                        profileItem = ResolveVmess(result, out msg);\n                    }\n                }\n                else if (result.StartsWith(Global.ssProtocol))\n                {\n                    msg = ResUI.ConfigurationFormatIncorrect;\n\n                    profileItem = ResolveSSLegacy(result) ?? ResolveSip002(result);\n                    if (profileItem == null)\n                    {\n                        return null;\n                    }\n                    if (profileItem.address.Length == 0 || profileItem.port == 0 || profileItem.security.Length == 0 || profileItem.id.Length == 0)\n                    {\n                        return null;\n                    }\n\n                    profileItem.configType = EConfigType.Shadowsocks;\n                }\n                else if (result.StartsWith(Global.socksProtocol))\n                {\n                    msg = ResUI.ConfigurationFormatIncorrect;\n\n                    profileItem = ResolveSocksNew(result) ?? ResolveSocks(result);\n                    if (profileItem == null)\n                    {\n                        return null;\n                    }\n                    if (profileItem.address.Length == 0 || profileItem.port == 0)\n                    {\n                        return null;\n                    }\n\n                    profileItem.configType = EConfigType.Socks;\n                }\n                else if (result.StartsWith(Global.trojanProtocol))\n                {\n                    msg = ResUI.ConfigurationFormatIncorrect;\n\n                    profileItem = ResolveTrojan(result);\n                }\n                else if (result.StartsWith(Global.vlessProtocol))\n                {\n                    profileItem = ResolveStdVLESS(result);\n                }\n                else\n                {\n                    msg = ResUI.NonvmessOrssProtocol;\n                    return null;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                msg = ResUI.Incorrectconfiguration;\n                return null;\n            }\n\n            return profileItem;\n        }\n\n        private static ProfileItem? ResolveVmess(string result, out string msg)\n        {\n            msg = string.Empty;\n            var profileItem = new ProfileItem\n            {\n                configType = EConfigType.VMess\n            };\n\n            result = result[Global.vmessProtocol.Length..];\n            result = Utils.Base64Decode(result);\n\n            //转成Json\n            VmessQRCode? vmessQRCode = Utils.FromJson<VmessQRCode>(result);\n            if (vmessQRCode == null)\n            {\n                msg = ResUI.FailedConversionConfiguration;\n                return null;\n            }\n\n            profileItem.network = Global.DefaultNetwork;\n            profileItem.headerType = Global.None;\n\n            profileItem.configVersion = Utils.ToInt(vmessQRCode.v);\n            profileItem.remarks = Utils.ToString(vmessQRCode.ps);\n            profileItem.address = Utils.ToString(vmessQRCode.add);\n            profileItem.port = Utils.ToInt(vmessQRCode.port);\n            profileItem.id = Utils.ToString(vmessQRCode.id);\n            profileItem.alterId = Utils.ToInt(vmessQRCode.aid);\n            profileItem.security = Utils.ToString(vmessQRCode.scy);\n\n            profileItem.security = !Utils.IsNullOrEmpty(vmessQRCode.scy) ? vmessQRCode.scy : Global.DefaultSecurity;\n            if (!Utils.IsNullOrEmpty(vmessQRCode.net))\n            {\n                profileItem.network = vmessQRCode.net;\n            }\n            if (!Utils.IsNullOrEmpty(vmessQRCode.type))\n            {\n                profileItem.headerType = vmessQRCode.type;\n            }\n\n            profileItem.requestHost = Utils.ToString(vmessQRCode.host);\n            profileItem.path = Utils.ToString(vmessQRCode.path);\n            profileItem.streamSecurity = Utils.ToString(vmessQRCode.tls);\n            profileItem.sni = Utils.ToString(vmessQRCode.sni);\n            profileItem.alpn = Utils.ToString(vmessQRCode.alpn);\n            profileItem.fingerprint = Utils.ToString(vmessQRCode.fp);\n            \n            profileItem.allowInsecure = Utils.ToString(vmessQRCode.allowInsecure);\n            return profileItem;\n        }\n\n        private static ProfileItem? ResolveVmess4Kitsunebi(string result)\n        {\n            ProfileItem profileItem = new()\n            {\n                configType = EConfigType.VMess\n            };\n            result = result[Global.vmessProtocol.Length..];\n            int indexSplit = result.IndexOf(\"?\");\n            if (indexSplit > 0)\n            {\n                result = result[..indexSplit];\n            }\n            result = Utils.Base64Decode(result);\n\n            string[] arr1 = result.Split('@');\n            if (arr1.Length != 2)\n            {\n                return null;\n            }\n            string[] arr21 = arr1[0].Split(':');\n            string[] arr22 = arr1[1].Split(':');\n            if (arr21.Length != 2 || arr22.Length != 2)\n            {\n                return null;\n            }\n\n            profileItem.address = arr22[0];\n            profileItem.port = Utils.ToInt(arr22[1]);\n            profileItem.security = arr21[0];\n            profileItem.id = arr21[1];\n\n            profileItem.network = Global.DefaultNetwork;\n            profileItem.headerType = Global.None;\n            profileItem.remarks = \"Alien\";\n\n            return profileItem;\n        }\n\n        private static ProfileItem? ResolveStdVmess(string result)\n        {\n            ProfileItem i = new()\n            {\n                configType = EConfigType.VMess,\n                security = \"auto\"\n            };\n\n            Uri u = new(result);\n\n            i.address = u.IdnHost;\n            i.port = u.Port;\n            i.remarks = u.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);\n            var q = HttpUtility.ParseQueryString(u.Query);\n\n            var m = StdVmessUserInfo.Match(u.UserInfo);\n            if (!m.Success) return null;\n\n            i.id = m.Groups[\"id\"].Value;\n\n            if (m.Groups[\"streamSecurity\"].Success)\n            {\n                i.streamSecurity = m.Groups[\"streamSecurity\"].Value;\n            }\n            switch (i.streamSecurity)\n            {\n                case \"tls\":\n                    break;\n\n                default:\n                    if (!string.IsNullOrWhiteSpace(i.streamSecurity))\n                        return null;\n                    break;\n            }\n\n            i.network = m.Groups[\"network\"].Value;\n            switch (i.network)\n            {\n                case \"tcp\":\n                    string t1 = q[\"type\"] ?? \"none\";\n                    i.headerType = t1;\n                    break;\n\n                case \"kcp\":\n                    i.headerType = q[\"type\"] ?? \"none\";\n                    break;\n\n                case \"ws\":\n                    string p1 = q[\"path\"] ?? \"/\";\n                    string h1 = q[\"host\"] ?? \"\";\n                    i.requestHost = Utils.UrlDecode(h1);\n                    i.path = p1;\n                    break;\n\n                case \"http\":\n                case \"h2\":\n                    i.network = \"h2\";\n                    string p2 = q[\"path\"] ?? \"/\";\n                    string h2 = q[\"host\"] ?? \"\";\n                    i.requestHost = Utils.UrlDecode(h2);\n                    i.path = p2;\n                    break;\n\n                case \"quic\":\n                    string s = q[\"security\"] ?? \"none\";\n                    string k = q[\"key\"] ?? \"\";\n                    string t3 = q[\"type\"] ?? \"none\";\n                    i.headerType = t3;\n                    i.requestHost = Utils.UrlDecode(s);\n                    i.path = k;\n                    break;\n\n                default:\n                    return null;\n            }\n            i.allowInsecure = q[\"allowInsecure\"] ?? \"\";\n            return i;\n        }\n\n        private static ProfileItem? ResolveSip002(string result)\n        {\n            Uri parsedUrl;\n            try\n            {\n                parsedUrl = new Uri(result);\n            }\n            catch (UriFormatException)\n            {\n                return null;\n            }\n            ProfileItem server = new()\n            {\n                remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),\n                address = parsedUrl.IdnHost,\n                port = parsedUrl.Port,\n            };\n            string rawUserInfo = parsedUrl.GetComponents(UriComponents.UserInfo, UriFormat.UriEscaped);\n            //2022-blake3\n            if (rawUserInfo.Contains(':'))\n            {\n                string[] userInfoParts = rawUserInfo.Split(new[] { ':' }, 2);\n                if (userInfoParts.Length != 2)\n                {\n                    return null;\n                }\n                server.security = userInfoParts[0];\n                server.id = Utils.UrlDecode(userInfoParts[1]);\n            }\n            else\n            {\n                // parse base64 UserInfo\n                string userInfo = Utils.Base64Decode(rawUserInfo);\n                string[] userInfoParts = userInfo.Split(new[] { ':' }, 2);\n                if (userInfoParts.Length != 2)\n                {\n                    return null;\n                }\n                server.security = userInfoParts[0];\n                server.id = userInfoParts[1];\n            }\n\n            NameValueCollection queryParameters = HttpUtility.ParseQueryString(parsedUrl.Query);\n            if (queryParameters[\"plugin\"] != null)\n            {\n                //obfs-host exists\n                var obfsHost = queryParameters[\"plugin\"].Split(';').FirstOrDefault(t => t.Contains(\"obfs-host\"));\n                if (queryParameters[\"plugin\"].Contains(\"obfs=http\") && !Utils.IsNullOrEmpty(obfsHost))\n                {\n                    obfsHost = obfsHost.Replace(\"obfs-host=\", \"\");\n                    server.network = Global.DefaultNetwork;\n                    server.headerType = Global.TcpHeaderHttp;\n                    server.requestHost = obfsHost;\n                }\n                else\n                {\n                    return null;\n                }\n            }\n            server.allowInsecure = queryParameters[\"allowInsecure\"] ?? \"\";\n            return server;\n        }\n\n        private static readonly Regex UrlFinder = new(@\"ss://(?<base64>[A-Za-z0-9+-/=_]+)(?:#(?<tag>\\S+))?\", RegexOptions.IgnoreCase | RegexOptions.Compiled);\n        private static readonly Regex DetailsParser = new(@\"^((?<method>.+?):(?<password>.*)@(?<hostname>.+?):(?<port>\\d+?))$\", RegexOptions.IgnoreCase | RegexOptions.Compiled);\n\n        private static ProfileItem? ResolveSSLegacy(string result)\n        {\n            var match = UrlFinder.Match(result);\n            if (!match.Success)\n                return null;\n\n            ProfileItem server = new();\n            var base64 = match.Groups[\"base64\"].Value.TrimEnd('/');\n            var tag = match.Groups[\"tag\"].Value;\n            if (!Utils.IsNullOrEmpty(tag))\n            {\n                server.remarks = Utils.UrlDecode(tag);\n            }\n            Match details;\n            try\n            {\n                details = DetailsParser.Match(Utils.Base64Decode(base64));\n            }\n            catch (FormatException)\n            {\n                return null;\n            }\n            if (!details.Success)\n                return null;\n            server.security = details.Groups[\"method\"].Value;\n            server.id = details.Groups[\"password\"].Value;\n            server.address = details.Groups[\"hostname\"].Value;\n            server.port = int.Parse(details.Groups[\"port\"].Value);\n            return server;\n        }\n\n        private static readonly Regex StdVmessUserInfo = new(\n            @\"^(?<network>[a-z]+)(\\+(?<streamSecurity>[a-z]+))?:(?<id>[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})$\", RegexOptions.Compiled);\n\n        private static ProfileItem? ResolveSocks(string result)\n        {\n            ProfileItem profileItem = new()\n            {\n                configType = EConfigType.Socks\n            };\n            result = result[Global.socksProtocol.Length..];\n            //remark\n            int indexRemark = result.IndexOf(\"#\");\n            if (indexRemark > 0)\n            {\n                try\n                {\n                    profileItem.remarks = Utils.UrlDecode(result.Substring(indexRemark + 1, result.Length - indexRemark - 1));\n                }\n                catch { }\n                result = result[..indexRemark];\n            }\n            //part decode\n            int indexS = result.IndexOf(\"@\");\n            if (indexS > 0)\n            {\n            }\n            else\n            {\n                result = Utils.Base64Decode(result);\n            }\n\n            string[] arr1 = result.Split('@');\n            if (arr1.Length != 2)\n            {\n                return null;\n            }\n            string[] arr21 = arr1[0].Split(':');\n            //string[] arr22 = arr1[1].Split(':');\n            int indexPort = arr1[1].LastIndexOf(\":\");\n            if (arr21.Length != 2 || indexPort < 0)\n            {\n                return null;\n            }\n            profileItem.address = arr1[1][..indexPort];\n            profileItem.port = Utils.ToInt(arr1[1][(indexPort + 1)..]);\n            profileItem.security = arr21[0];\n            profileItem.id = arr21[1];\n\n            return profileItem;\n        }\n\n        private static ProfileItem? ResolveSocksNew(string result)\n        {\n            Uri parsedUrl;\n            try\n            {\n                parsedUrl = new Uri(result);\n            }\n            catch (UriFormatException)\n            {\n                return null;\n            }\n            ProfileItem server = new()\n            {\n                remarks = parsedUrl.GetComponents(UriComponents.Fragment, UriFormat.Unescaped),\n                address = parsedUrl.IdnHost,\n                port = parsedUrl.Port,\n            };\n\n            // parse base64 UserInfo\n            string rawUserInfo = parsedUrl.GetComponents(UriComponents.UserInfo, UriFormat.Unescaped);\n            string userInfo = Utils.Base64Decode(rawUserInfo);\n            string[] userInfoParts = userInfo.Split(new[] { ':' }, 2);\n            if (userInfoParts.Length == 2)\n            {\n                server.security = userInfoParts[0];\n                server.id = userInfoParts[1];\n            }\n\n            return server;\n        }\n\n        private static ProfileItem ResolveTrojan(string result)\n        {\n            ProfileItem item = new()\n            {\n                configType = EConfigType.Trojan\n            };\n\n            Uri url = new(result);\n\n            item.address = url.IdnHost;\n            item.port = url.Port;\n            item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);\n            item.id = url.UserInfo;\n\n            var query = HttpUtility.ParseQueryString(url.Query);\n            ResolveStdTransport(query, ref item);\n\n            return item;\n        }\n\n        private static ProfileItem ResolveStdVLESS(string result)\n        {\n            ProfileItem item = new()\n            {\n                configType = EConfigType.VLESS,\n                security = \"none\"\n            };\n\n            Uri url = new(result);\n\n            item.address = url.IdnHost;\n            item.port = url.Port;\n            item.remarks = url.GetComponents(UriComponents.Fragment, UriFormat.Unescaped);\n            item.id = url.UserInfo;\n\n            var query = HttpUtility.ParseQueryString(url.Query);\n            item.security = query[\"encryption\"] ?? \"none\";\n            item.streamSecurity = query[\"security\"] ?? \"\";\n            ResolveStdTransport(query, ref item);\n\n            return item;\n        }\n\n        private static int ResolveStdTransport(NameValueCollection query, ref ProfileItem item)\n        {\n            item.flow = query[\"flow\"] ?? \"\";\n            item.streamSecurity = query[\"security\"] ?? \"\";\n            item.sni = query[\"sni\"] ?? \"\";\n            item.alpn = Utils.UrlDecode(query[\"alpn\"] ?? \"\");\n            item.allowInsecure= query[\"allowInsecure\"] ?? \"\";\n            item.fingerprint = Utils.UrlDecode(query[\"fp\"] ?? \"\");\n            item.fragment = Utils.UrlDecode(query[\"fragment\"] ?? \"\");\n            item.publicKey = Utils.UrlDecode(query[\"pbk\"] ?? \"\");\n            item.shortId = Utils.UrlDecode(query[\"sid\"] ?? \"\");\n            item.spiderX = Utils.UrlDecode(query[\"spx\"] ?? \"\");\n\n            item.network = query[\"type\"] ?? \"tcp\";\n            switch (item.network)\n            {\n                case \"tcp\":\n                    item.headerType = query[\"headerType\"] ?? \"none\";\n                    item.requestHost = Utils.UrlDecode(query[\"host\"] ?? \"\");\n\n                    break;\n\n                case \"kcp\":\n                    item.headerType = query[\"headerType\"] ?? \"none\";\n                    item.path = Utils.UrlDecode(query[\"seed\"] ?? \"\");\n                    break;\n\n                case \"ws\":\n                    item.requestHost = Utils.UrlDecode(query[\"host\"] ?? \"\");\n                    item.path = Utils.UrlDecode(query[\"path\"] ?? \"/\");\n                    break;\n\n                case \"http\":\n                case \"h2\":\n                    item.network = \"h2\";\n                    item.requestHost = Utils.UrlDecode(query[\"host\"] ?? \"\");\n                    item.path = Utils.UrlDecode(query[\"path\"] ?? \"/\");\n                    break;\n\n                case \"quic\":\n                    item.headerType = query[\"headerType\"] ?? \"none\";\n                    item.requestHost = query[\"quicSecurity\"] ?? \"none\";\n                    item.path = Utils.UrlDecode(query[\"key\"] ?? \"\");\n                    break;\n\n                case \"grpc\":\n                    item.path = Utils.UrlDecode(query[\"serviceName\"] ?? \"\");\n                    item.headerType = Utils.UrlDecode(query[\"mode\"] ?? Global.GrpcgunMode);\n                    break;\n\n                default:\n                    break;\n            }\n            return 0;\n        }\n\n        #endregion ImportShareUrl\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/SpeedtestHandler.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Net;\nusing System.Net.NetworkInformation;\nusing System.Net.Sockets;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    internal class SpeedtestHandler\n    {\n        private Config _config;\n        private CoreHandler _coreHandler;\n        private List<ServerTestItem> _selecteds;\n        private ESpeedActionType _actionType;\n        private Action<string, string, string> _updateFunc;\n\n        public SpeedtestHandler(Config config)\n        {\n            _config = config;\n        }\n\n        public SpeedtestHandler(Config config, CoreHandler coreHandler, List<ProfileItem> selecteds, ESpeedActionType actionType, Action<string, string, string> update)\n        {\n            _config = config;\n            _coreHandler = coreHandler;\n            _actionType = actionType;\n            _updateFunc = update;\n\n            _selecteds = new List<ServerTestItem>();\n            foreach (var it in selecteds)\n            {\n                if (it.configType == EConfigType.Custom)\n                {\n                   // continue;\n                }\n                if (it.port <= 0)\n                {\n                 //   continue;\n                }\n                _selecteds.Add(new ServerTestItem()\n                {\n                    indexId = it.indexId,\n                    address = it.address,\n                    port = it.port,\n                    configType = it.configType\n                });\n            }\n            //clear test result\n            foreach (var it in _selecteds)\n            {\n                switch (actionType)\n                {\n                    case ESpeedActionType.Ping:\n                    case ESpeedActionType.Tcping:\n                    case ESpeedActionType.Realping:\n                        UpdateFunc(it.indexId, ResUI.Speedtesting, \"\");\n                        ProfileExHandler.Instance.SetTestDelay(it.indexId, \"0\");\n                        break;\n\n                    case ESpeedActionType.Speedtest:\n                        UpdateFunc(it.indexId, \"\", ResUI.SpeedtestingWait);\n                        ProfileExHandler.Instance.SetTestSpeed(it.indexId, \"0\");\n                        break;\n\n                    case ESpeedActionType.Mixedtest:\n                        UpdateFunc(it.indexId, ResUI.Speedtesting, ResUI.SpeedtestingWait);\n                        ProfileExHandler.Instance.SetTestDelay(it.indexId, \"0\");\n                        ProfileExHandler.Instance.SetTestSpeed(it.indexId, \"0\");\n                        break;\n                }\n            }\n\n            switch (actionType)\n            {\n                case ESpeedActionType.Ping:\n                    Task.Run(RunPing);\n                    break;\n\n                case ESpeedActionType.Tcping:\n                    Task.Run(RunTcping);\n                    break;\n\n                case ESpeedActionType.Realping:\n                    Task.Run(RunRealPing);\n                    break;\n\n                case ESpeedActionType.Speedtest:\n                    Task.Run(RunSpeedTestAsync);\n                    break;\n\n                case ESpeedActionType.Mixedtest:\n                    Task.Run(RunMixedtestAsync);\n                    break;\n            }\n        }\n\n        private void RunPingSub(Action<ServerTestItem> updateFun)\n        {\n            try\n            {\n                foreach (var it in _selecteds.Where(it => it.configType != EConfigType.Custom))\n                {\n                    try\n                    {\n                        Task.Run(() => updateFun(it));\n                    }\n                    catch (Exception ex)\n                    {\n                        Utils.SaveLog(ex.Message, ex);\n                    }\n                }\n\n                Thread.Sleep(10);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private void RunPing()\n        {\n            RunPingSub((ServerTestItem it) =>\n            {\n                long time = Ping(it.address);\n                var output = FormatOut(time, Global.DelayUnit);\n\n                ProfileExHandler.Instance.SetTestDelay(it.indexId, output);\n                UpdateFunc(it.indexId, output);\n            });\n        }\n\n        private void RunTcping()\n        {\n            RunPingSub((ServerTestItem it) =>\n            {\n                int time = GetTcpingTime(it.address, it.port);\n                var output = FormatOut(time, Global.DelayUnit);\n\n                ProfileExHandler.Instance.SetTestDelay(it.indexId, output);\n                UpdateFunc(it.indexId, output);\n            });\n        }\n\n        private Task RunRealPing()\n        {\n            int pid = -1;\n            try\n            {\n                string msg = string.Empty;\n\n                pid = _coreHandler.LoadCoreConfigString(_selecteds);\n                if (pid < 0)\n                {\n                    UpdateFunc(\"\", ResUI.FailedToRunCore);\n                    return Task.CompletedTask;\n                }\n\n                DownloadHandle downloadHandle = new DownloadHandle();\n                //Thread.Sleep(5000);\n                List<Task> tasks = new();\n                foreach (var it in _selecteds)\n                {\n                    if (!it.allowTest)\n                    {\n                        continue;\n                    }\n                    if (it.configType == EConfigType.Custom)\n                    {\n                        continue;\n                    }\n                    tasks.Add(Task.Run(async () =>\n                    {\n                        try\n                        {\n                            WebProxy webProxy = new(Global.Loopback, it.port);\n                            string output = await GetRealPingTime(downloadHandle, webProxy);\n\n                            ProfileExHandler.Instance.SetTestDelay(it.indexId, output);\n                            UpdateFunc(it.indexId, output);\n                            int.TryParse(output, out int delay);\n                            it.delay = delay;\n                        }\n                        catch (Exception ex)\n                        {\n                            Utils.SaveLog(ex.Message, ex);\n                        }\n                    }));\n                    //Thread.Sleep(100);\n                }\n                Task.WaitAll(tasks.ToArray());\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            finally\n            {\n                if (pid > 0) _coreHandler.CoreStopPid(pid);\n                ProfileExHandler.Instance.SaveTo();\n            }\n\n            return Task.CompletedTask;\n        }\n\n        private async Task RunSpeedTestAsync()\n        {\n            int pid = -1;\n            //if (_actionType == ESpeedActionType.Mixedtest)\n            //{\n            //    _selecteds = _selecteds.OrderBy(t => t.delay).ToList();\n            //}\n\n            pid = _coreHandler.LoadCoreConfigString(_selecteds);\n            if (pid < 0)\n            {\n                UpdateFunc(\"\", ResUI.FailedToRunCore);\n                return;\n            }\n\n            string url = _config.speedTestItem.speedTestUrl;\n            var timeout = _config.speedTestItem.speedTestTimeout;\n\n            DownloadHandle downloadHandle = new();\n\n            foreach (var it in _selecteds)\n            {\n                if (!it.allowTest)\n                {\n                    continue;\n                }\n                if (it.configType == EConfigType.Custom)\n                {\n                    continue;\n                }\n                //if (it.delay < 0)\n                //{\n                //    UpdateFunc(it.indexId, \"\", ResUI.SpeedtestingSkip);\n                //    continue;\n                //}\n                ProfileExHandler.Instance.SetTestSpeed(it.indexId, \"-1\");\n                UpdateFunc(it.indexId, \"\", ResUI.Speedtesting);\n\n                var item = LazyConfig.Instance.GetProfileItem(it.indexId);\n                if (item is null) continue;\n\n                WebProxy webProxy = new(Global.Loopback, it.port);\n\n                await downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>\n                {\n                    decimal.TryParse(msg, out decimal dec);\n                    if (dec > 0)\n                    {\n                        ProfileExHandler.Instance.SetTestSpeed(it.indexId, msg);\n                    }\n                    UpdateFunc(it.indexId, \"\", msg);\n                });\n            }\n\n            if (pid > 0)\n            {\n                _coreHandler.CoreStopPid(pid);\n            }\n            UpdateFunc(\"\", ResUI.SpeedtestingCompleted);\n            ProfileExHandler.Instance.SaveTo();\n        }\n\n        private async Task RunSpeedTestMulti()\n        {\n            int pid = -1;\n            pid = _coreHandler.LoadCoreConfigString(_selecteds);\n            if (pid < 0)\n            {\n                UpdateFunc(\"\", ResUI.FailedToRunCore);\n                return;\n            }\n\n            string url = _config.speedTestItem.speedTestUrl;\n            var timeout = _config.speedTestItem.speedTestTimeout;\n\n            DownloadHandle downloadHandle = new();\n\n            foreach (var it in _selecteds)\n            {\n                if (!it.allowTest)\n                {\n                    continue;\n                }\n                if (it.configType == EConfigType.Custom)\n                {\n                    continue;\n                }\n                if (it.delay < 0)\n                {\n                    UpdateFunc(it.indexId, \"\", ResUI.SpeedtestingSkip);\n                    continue;\n                }\n                ProfileExHandler.Instance.SetTestSpeed(it.indexId, \"-1\");\n                UpdateFunc(it.indexId, \"\", ResUI.Speedtesting);\n\n                var item = LazyConfig.Instance.GetProfileItem(it.indexId);\n                if (item is null) continue;\n\n                WebProxy webProxy = new(Global.Loopback, it.port);\n                _ = downloadHandle.DownloadDataAsync(url, webProxy, timeout, (bool success, string msg) =>\n                {\n                    decimal.TryParse(msg, out decimal dec);\n                    if (dec > 0)\n                    {\n                        ProfileExHandler.Instance.SetTestSpeed(it.indexId, msg);\n                    }\n                    UpdateFunc(it.indexId, \"\", msg);\n                });\n                Thread.Sleep(2000);\n            }\n\n            Thread.Sleep((timeout + 2) * 1000);\n\n            if (pid > 0)\n            {\n                _coreHandler.CoreStopPid(pid);\n            }\n            UpdateFunc(\"\", ResUI.SpeedtestingCompleted);\n            ProfileExHandler.Instance.SaveTo();\n        }\n\n        private async Task RunMixedtestAsync()\n        {\n            await RunRealPing();\n\n            Thread.Sleep(1000);\n\n            await RunSpeedTestMulti();\n        }\n\n        public async Task<string> GetRealPingTime(DownloadHandle downloadHandle, IWebProxy webProxy)\n        {\n            int responseTime = await downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10);\n            responseTime = await downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10);\n            if (responseTime<0)\n                responseTime = await downloadHandle.GetRealPingTime(_config.speedTestItem.speedPingTestUrl, webProxy, 10);\n            //string output = Utils.IsNullOrEmpty(status) ? FormatOut(responseTime, \"ms\") : status;\n            return FormatOut(responseTime, Global.DelayUnit);\n        }\n\n        private int GetTcpingTime(string url, int port)\n        {\n            int responseTime = -1;\n\n            try\n            {\n                if (!IPAddress.TryParse(url, out IPAddress ipAddress))\n                {\n                    IPHostEntry ipHostInfo = System.Net.Dns.GetHostEntry(url);\n                    ipAddress = ipHostInfo.AddressList[0];\n                }\n\n                Stopwatch timer = new();\n                timer.Start();\n\n                IPEndPoint endPoint = new(ipAddress, port);\n                using Socket clientSocket = new(endPoint.AddressFamily, SocketType.Stream, ProtocolType.Tcp);\n\n                IAsyncResult result = clientSocket.BeginConnect(endPoint, null, null);\n                if (!result.AsyncWaitHandle.WaitOne(TimeSpan.FromSeconds(5)))\n                    throw new TimeoutException(\"connect timeout (5s): \" + url);\n                clientSocket.EndConnect(result);\n\n                timer.Stop();\n                responseTime = timer.Elapsed.Milliseconds;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return responseTime;\n        }\n\n        /// <summary>\n        /// Ping\n        /// </summary>\n        /// <param name=\"host\"></param>\n        /// <returns></returns>\n        public long Ping(string host)\n        {\n            long roundtripTime = -1;\n            try\n            {\n                int timeout = 30;\n                int echoNum = 2;\n                using Ping pingSender = new();\n                for (int i = 0; i < echoNum; i++)\n                {\n                    PingReply reply = pingSender.Send(host, timeout);\n                    if (reply.Status == IPStatus.Success)\n                    {\n                        if (reply.RoundtripTime < 0)\n                        {\n                            continue;\n                        }\n                        if (roundtripTime < 0 || reply.RoundtripTime < roundtripTime)\n                        {\n                            roundtripTime = reply.RoundtripTime;\n                        }\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                return -1;\n            }\n            return roundtripTime;\n        }\n\n        private string FormatOut(object time, string unit)\n        {\n            //if (time.ToString().Equals(\"-1\"))\n            //{\n            //    return \"Timeout\";\n            //}\n            return $\"{time}\";\n        }\n\n        private void UpdateFunc(string indexId, string delay, string speed = \"\")\n        {\n            _updateFunc(indexId, delay, speed);\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/StatisticsHandler.cs",
    "content": "﻿using Grpc.Core;\nusing Grpc.Net.Client;\nusing ProtosLib.Statistics;\nusing System.Net;\nusing System.Net.Sockets;\nusing v2rayN.Base;\nusing v2rayN.Mode;\n\nnamespace v2rayN.Handler\n{\n    internal class StatisticsHandler\n    {\n        private Mode.Config config_;\n        private GrpcChannel _channel;\n        private StatsService.StatsServiceClient _client;\n        private bool _exitFlag;\n        private ServerStatItem? _serverStatItem;\n        private List<ServerStatItem> _lstServerStat;\n        public List<ServerStatItem> ServerStat => _lstServerStat;\n\n        private Action<ServerSpeedItem> _updateFunc;\n\n        public bool Enable\n        {\n            get; set;\n        }\n\n        public StatisticsHandler(Mode.Config config, Action<ServerSpeedItem> update)\n        {\n            config_ = config;\n            Enable = config.guiItem.enableStatistics;\n            _updateFunc = update;\n            _exitFlag = false;\n\n            Init();\n            GrpcInit();\n\n            Task.Run(Run);\n        }\n\n        private void GrpcInit()\n        {\n            if (_channel == null)\n            {\n                Global.statePort = GetFreePort();\n\n                _channel = GrpcChannel.ForAddress($\"{Global.httpProtocol}{Global.Loopback}:{Global.statePort}\");\n                _client = new StatsService.StatsServiceClient(_channel);\n            }\n        }\n\n        public void Close()\n        {\n            try\n            {\n                _exitFlag = true;\n                //channel_.ShutdownAsync();\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        public async void Run()\n        {\n            while (!_exitFlag)\n            {\n                try\n                {\n                    if (Enable && _channel.State == ConnectivityState.Ready)\n                    {\n                        QueryStatsResponse? res = null;\n                        try\n                        {\n                            res = await _client.QueryStatsAsync(new QueryStatsRequest() { Pattern = \"\", Reset = true });\n                        }\n                        catch (Exception ex)\n                        {\n                            //Utils.SaveLog(ex.Message, ex);\n                        }\n\n                        if (res != null)\n                        {\n                            GetServerStatItem(config_.indexId);\n                            ParseOutput(res.Stat, out ServerSpeedItem server);\n\n                            if (server.proxyUp != 0 || server.proxyDown != 0)\n                            {\n                                _serverStatItem.todayUp += server.proxyUp;\n                                _serverStatItem.todayDown += server.proxyDown;\n                                _serverStatItem.totalUp += server.proxyUp;\n                                _serverStatItem.totalDown += server.proxyDown;\n                            }\n                            if (Global.ShowInTaskbar)\n                            {\n                                server.indexId = config_.indexId;\n                                server.todayUp = _serverStatItem.todayUp;\n                                server.todayDown = _serverStatItem.todayDown;\n                                server.totalUp = _serverStatItem.totalUp;\n                                server.totalDown = _serverStatItem.totalDown;\n                                _updateFunc(server);\n                            }\n                        }\n                    }\n                    var sleep = config_.guiItem.statisticsFreshRate < 1 ? 1 : config_.guiItem.statisticsFreshRate;\n                    Thread.Sleep(1000 * sleep);\n                    await _channel.ConnectAsync();\n                }\n                catch\n                {\n                }\n            }\n        }\n\n        public void ClearAllServerStatistics()\n        {\n            SqliteHelper.Instance.Execute($\"delete from ServerStatItem \");\n            _serverStatItem = null;\n            _lstServerStat = new();\n        }\n\n        public void SaveTo()\n        {\n            try\n            {\n                SqliteHelper.Instance.UpdateAll(_lstServerStat);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private void Init()\n        {\n            SqliteHelper.Instance.Execute($\"delete from ServerStatItem where indexId not in ( select indexId from ProfileItem )\");\n\n            long ticks = DateTime.Now.Date.Ticks;\n            SqliteHelper.Instance.Execute($\"update ServerStatItem set todayUp = 0,todayDown=0,dateNow={ticks} where dateNow<>{ticks}\");\n\n            _lstServerStat = SqliteHelper.Instance.Table<ServerStatItem>().ToList();\n        }\n\n        private void GetServerStatItem(string indexId)\n        {\n            long ticks = DateTime.Now.Date.Ticks;\n            if (_serverStatItem != null && _serverStatItem.indexId != indexId)\n            {\n                _serverStatItem = null;\n            }\n\n            if (_serverStatItem == null)\n            {\n                _serverStatItem = _lstServerStat.FirstOrDefault(t => t.indexId == indexId);\n                if (_serverStatItem == null)\n                {\n                    _serverStatItem = new ServerStatItem\n                    {\n                        indexId = indexId,\n                        totalUp = 0,\n                        totalDown = 0,\n                        todayUp = 0,\n                        todayDown = 0,\n                        dateNow = ticks\n                    };\n                    SqliteHelper.Instance.Replace(_serverStatItem);\n                    _lstServerStat.Add(_serverStatItem);\n                }\n            }\n\n            if (_serverStatItem.dateNow != ticks)\n            {\n                _serverStatItem.todayUp = 0;\n                _serverStatItem.todayDown = 0;\n                _serverStatItem.dateNow = ticks;\n            }\n        }\n\n        private void ParseOutput(Google.Protobuf.Collections.RepeatedField<Stat> source, out ServerSpeedItem server)\n        {\n            server = new();\n            try\n            {\n                foreach (Stat stat in source)\n                {\n                    string name = stat.Name;\n                    long value = stat.Value / 1024;    //KByte\n                    string[] nStr = name.Split(\">>>\".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);\n                    string type = \"\";\n\n                    name = name.Trim();\n\n                    name = nStr[1];\n                    type = nStr[3];\n\n                    if (name == Global.agentTag)\n                    {\n                        if (type == \"uplink\")\n                        {\n                            server.proxyUp = value;\n                        }\n                        else if (type == \"downlink\")\n                        {\n                            server.proxyDown = value;\n                        }\n                    }\n                    else if (name == Global.directTag)\n                    {\n                        if (type == \"uplink\")\n                        {\n                            server.directUp = value;\n                        }\n                        else if (type == \"downlink\")\n                        {\n                            server.directDown = value;\n                        }\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                //Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private int GetFreePort()\n        {\n            int defaultPort = 28123;\n            try\n            {\n                // TCP stack please do me a favor\n                TcpListener l = new(IPAddress.Loopback, 0);\n                l.Start();\n                int port = ((IPEndPoint)l.LocalEndpoint).Port;\n                l.Stop();\n                return port;\n            }\n            catch (Exception ex)\n            {\n                // in case access denied\n                Utils.SaveLog(ex.Message, ex);\n                return defaultPort;\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/SysProxyHandle.cs",
    "content": "﻿using PacLib;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Text;\nusing v2rayN.Mode;\nusing v2rayN.Properties;\nusing v2rayN.Tool;\n\nnamespace v2rayN.Handler\n{\n    public static class SysProxyHandle\n    {\n        //private const string _userWininetConfigFile = \"user-wininet.json\";\n\n        //private static string _queryStr;\n\n        // In general, this won't change\n        // format:\n        //  <flags><CR-LF>\n        //  <proxy-server><CR-LF>\n        //  <bypass-list><CR-LF>\n        //  <pac-url>\n        private static SysproxyConfig? _userSettings = null;\n\n        private enum RET_ERRORS : int\n        {\n            RET_NO_ERROR = 0,\n            INVALID_FORMAT = 1,\n            NO_PERMISSION = 2,\n            SYSCALL_FAILED = 3,\n            NO_MEMORY = 4,\n            INVAILD_OPTION_COUNT = 5,\n        };\n\n        static SysProxyHandle()\n        {\n            try\n            {\n                FileManager.UncompressFile(Utils.GetTempPath(\"sysproxy.exe\"),\n                    Environment.Is64BitOperatingSystem ? Resources.sysproxy64_exe : Resources.sysproxy_exe);\n            }\n            catch (IOException ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        public static bool UpdateSysProxy(Config config, bool forceDisable)\n        {\n            var type = config.sysProxyType;\n\n            if (forceDisable && type != ESysProxyType.Unchanged)\n            {\n                type = ESysProxyType.ForcedClear;\n            }\n\n            try\n            {\n                int port = LazyConfig.Instance.GetLocalPort(Global.InboundHttp);\n                int portSocks = LazyConfig.Instance.GetLocalPort(Global.InboundSocks);\n                int portPac = LazyConfig.Instance.GetLocalPort(ESysProxyType.Pac.ToString());\n                if (port <= 0)\n                {\n                    return false;\n                }\n                if (type == ESysProxyType.ForcedChange)\n                {\n                    var strExceptions = $\"{config.constItem.defIEProxyExceptions};{config.systemProxyExceptions}\";\n\n                    var strProxy = string.Empty;\n                    if (Utils.IsNullOrEmpty(config.systemProxyAdvancedProtocol))\n                    {\n                        strProxy = $\"{Global.Loopback}:{port}\";\n                    }\n                    else\n                    {\n                        strProxy = config.systemProxyAdvancedProtocol\n                            .Replace(\"{ip}\", Global.Loopback)\n                            .Replace(\"{http_port}\", port.ToString())\n                            .Replace(\"{socks_port}\", portSocks.ToString());\n                    }\n                    ProxySetting.SetProxy(strProxy, strExceptions, 2);\n                    SetIEProxy(true, strProxy, strExceptions);\n                }\n                else if (type == ESysProxyType.ForcedClear)\n                {\n                    ProxySetting.UnsetProxy();\n                    ResetIEProxy();\n                }\n                else if (type == ESysProxyType.Unchanged)\n                {\n                }\n                else if (type == ESysProxyType.Pac)\n                {\n                    PacHandler.Start(Utils.GetConfigPath(), port, portPac);\n                    var strProxy = $\"{Global.httpProtocol}{Global.Loopback}:{portPac}/pac?t={DateTime.Now.Ticks}\";\n                    ProxySetting.SetProxy(strProxy, \"\", 4);\n                    SetIEProxy(false, strProxy, \"\");\n                }\n\n                if (type != ESysProxyType.Pac)\n                {\n                    PacHandler.Stop();\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return true;\n        }\n\n        public static void ResetIEProxy4WindowsShutDown()\n        {\n            try\n            {\n                //TODO To be verified\n                Utils.RegWriteValue(@\"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\", \"ProxyEnable\", 0);\n            }\n            catch\n            {\n            }\n        }\n\n        public static void SetIEProxy(bool global, string strProxy, string strExceptions)\n        {\n            string arguments = global\n                ? $\"global {strProxy} {strExceptions}\"\n                : $\"pac {strProxy}\";\n\n            ExecSysproxy(arguments);\n        }\n\n        // set system proxy to 1 (null) (null) (null)\n        public static void ResetIEProxy()\n        {\n            ExecSysproxy(\"set 1 - - -\");\n        }\n\n        private static void ExecSysproxy(string arguments)\n        {\n            // using event to avoid hanging when redirect standard output/error\n            // ref: https://stackoverflow.com/questions/139593/processstartinfo-hanging-on-waitforexit-why\n            // and http://blog.csdn.net/zhangweixing0/article/details/7356841\n            using AutoResetEvent outputWaitHandle = new(false);\n            using AutoResetEvent errorWaitHandle = new(false);\n            using Process process = new();\n\n            // Configure the process using the StartInfo properties.\n            process.StartInfo.FileName = Utils.GetTempPath(\"sysproxy.exe\");\n            process.StartInfo.Arguments = arguments;\n            process.StartInfo.WorkingDirectory = Utils.GetTempPath();\n            process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;\n            process.StartInfo.UseShellExecute = false;\n            process.StartInfo.RedirectStandardError = true;\n            process.StartInfo.RedirectStandardOutput = true;\n\n            // Need to provide encoding info, or output/error strings we got will be wrong.\n            process.StartInfo.StandardOutputEncoding = Encoding.Unicode;\n            process.StartInfo.StandardErrorEncoding = Encoding.Unicode;\n\n            process.StartInfo.CreateNoWindow = true;\n\n            StringBuilder output = new(1024);\n            StringBuilder error = new(1024);\n\n            process.OutputDataReceived += (sender, e) =>\n            {\n                if (e.Data == null)\n                {\n                    outputWaitHandle.Set();\n                }\n                else\n                {\n                    output.AppendLine(e.Data);\n                }\n            };\n            process.ErrorDataReceived += (sender, e) =>\n            {\n                if (e.Data == null)\n                {\n                    errorWaitHandle.Set();\n                }\n                else\n                {\n                    error.AppendLine(e.Data);\n                }\n            };\n            try\n            {\n                process.Start();\n\n                process.BeginErrorReadLine();\n                process.BeginOutputReadLine();\n\n                process.WaitForExit();\n            }\n            catch (System.ComponentModel.Win32Exception e)\n            {\n                // log the arguments\n                throw new Exception(process.StartInfo.Arguments);\n            }\n            string stderr = error.ToString();\n            string stdout = output.ToString();\n\n            int exitCode = process.ExitCode;\n            if (exitCode != (int)RET_ERRORS.RET_NO_ERROR)\n            {\n                throw new Exception(stderr);\n            }\n\n            //if (arguments == \"query\")\n            //{\n            //    if (stdout.IsNullOrWhiteSpace() || stdout.IsNullOrEmpty())\n            //    {\n            //        throw new Exception(\"failed to query wininet settings\");\n            //    }\n            //    _queryStr = stdout;\n            //}\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/TunHandler.cs",
    "content": "﻿using System.Diagnostics;\nusing System.IO;\nusing System.Reactive.Linq;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Base\n{\n    public sealed class TunHandler\n    {\n        private static readonly Lazy<TunHandler> _instance = new(() => new());\n        public static TunHandler Instance => _instance.Value;\n        private string _tunConfigName = \"tunConfig.json\";\n        private static Config _config;\n        private CoreInfo coreInfo;\n        private Process? _process;\n        private static int _socksPort;\n        private static bool _needRestart = true;\n        private static bool _isRunning = false;\n\n        public TunHandler()\n        {\n            _config = LazyConfig.Instance.GetConfig();\n\n            Observable.Interval(TimeSpan.FromSeconds(10))\n                 .Subscribe(x =>\n                 {\n                     if (_isRunning && _config.tunModeItem.enableTun)\n                     {\n                         if (_process == null || _process.HasExited)\n                         {\n                             if (Init() == false)\n                             {\n                                 return;\n                             }\n                             CoreStart();\n                             Utils.SaveLog(\"Tun mode monitors restart\");\n                         }\n                     }\n                 });\n        }\n\n        public void Start()\n        {\n            var socksPort = LazyConfig.Instance.GetLocalPort(Global.InboundSocks);\n\n            if (socksPort == _socksPort\n                && _process != null\n                && !_process.HasExited)\n            {\n                _needRestart = false;\n            }\n\n            _socksPort = socksPort;\n\n            if (_needRestart)\n            {\n                CoreStop();\n                if (Init() == false)\n                {\n                    return;\n                }\n                CoreStartTest();\n                CoreStart();\n            }\n        }\n\n        public void Stop()\n        {\n            CoreStop();\n        }\n\n        private bool Init()\n        {\n            coreInfo = LazyConfig.Instance.GetCoreInfo(ECoreType.sing_box);\n            //Template\n            string configStr = Utils.GetEmbedText(Global.TunSingboxFileName);\n            if (!Utils.IsNullOrEmpty(_config.tunModeItem.customTemplate) && File.Exists(_config.tunModeItem.customTemplate))\n            {\n                var customTemplate = File.ReadAllText(_config.tunModeItem.customTemplate);\n                if (!Utils.IsNullOrEmpty(customTemplate))\n                {\n                    configStr = customTemplate;\n                }\n            }\n            if (Utils.IsNullOrEmpty(configStr))\n            {\n                return false;\n            }\n\n            //settings\n            if (_config.tunModeItem.mtu <= 0)\n            {\n                _config.tunModeItem.mtu = Convert.ToInt32(Global.TunMtus[0]);\n            }\n            if (Utils.IsNullOrEmpty(_config.tunModeItem.stack))\n            {\n                _config.tunModeItem.stack = Global.TunStacks[0];\n            }\n            configStr = configStr.Replace(\"$mtu$\", $\"{_config.tunModeItem.mtu}\");\n            configStr = configStr.Replace(\"$strict_route$\", $\"{_config.tunModeItem.strictRoute.ToString().ToLower()}\");\n            configStr = configStr.Replace(\"$stack$\", $\"{_config.tunModeItem.stack}\");\n\n            //logs\n            configStr = configStr.Replace(\"$log_disabled$\", $\"{(!_config.tunModeItem.enabledLog).ToString().ToLower()}\");\n            if (_config.tunModeItem.showWindow)\n            {\n                configStr = configStr.Replace(\"$log_output$\", $\"\");\n            }\n            else\n            {\n                var dtNow = DateTime.Now;\n                var log_output = $\"\\\"output\\\": \\\"{Utils.GetLogPath($\"singbox_{dtNow:yyyy-MM-dd}.txt\")}\\\", \";\n                configStr = configStr.Replace(\"$log_output$\", $\"{log_output.Replace(@\"\\\", @\"\\\\\")}\");\n            }\n\n            //port\n            configStr = configStr.Replace(\"$socksPort$\", $\"{_socksPort}\");\n\n            //dns\n            string dnsObject = String.Empty;\n            if (_config.tunModeItem.bypassMode)\n            {\n                dnsObject = _config.tunModeItem.directDNS;\n            }\n            else\n            {\n                dnsObject = _config.tunModeItem.proxyDNS;\n            }\n            if (dnsObject.IsNullOrEmpty() || Utils.ParseJson(dnsObject)?.ContainsKey(\"servers\") == false)\n            {\n                dnsObject = Utils.GetEmbedText(Global.TunSingboxDNSFileName);\n            }\n            configStr = configStr.Replace(\"$dns_object$\", dnsObject);\n\n            //exe\n            routingDirectExe(out List<string> lstDnsExe, out List<string> lstDirectExe);\n            string strDns = string.Join(\"\\\",\\\"\", lstDnsExe.ToArray());\n            configStr = configStr.Replace(\"$dnsProcessName$\", $\"\\\"{strDns}\\\"\");\n\n            string strDirect = string.Join(\"\\\",\\\"\", lstDirectExe.ToArray());\n            configStr = configStr.Replace(\"$directProcessName$\", $\"\\\"{strDirect}\\\"\");\n\n            if (_config.tunModeItem.bypassMode)\n            {\n                //direct ips\n                if (_config.tunModeItem.directIP != null && _config.tunModeItem.directIP.Count > 0)\n                {\n                    var ips = new { outbound = \"direct\", ip_cidr = _config.tunModeItem.directIP };\n                    configStr = configStr.Replace(\"$ruleDirectIPs$\", \",\" + Utils.ToJson(ips));\n                }\n                //direct process\n                if (_config.tunModeItem.directProcess != null && _config.tunModeItem.directProcess.Count > 0)\n                {\n                    var process = new { outbound = \"direct\", process_name = _config.tunModeItem.directProcess };\n                    configStr = configStr.Replace(\"$ruleDirectProcess$\", \",\" + Utils.ToJson(process));\n                }\n            }\n            else\n            {\n                //proxy ips\n                if (_config.tunModeItem.proxyIP != null && _config.tunModeItem.proxyIP.Count > 0)\n                {\n                    var ips = new { outbound = \"proxy\", ip_cidr = _config.tunModeItem.proxyIP };\n                    configStr = configStr.Replace(\"$ruleProxyIPs$\", \",\" + Utils.ToJson(ips));\n                }\n                //proxy process\n                if (_config.tunModeItem.proxyProcess != null && _config.tunModeItem.proxyProcess.Count > 0)\n                {\n                    var process = new { outbound = \"proxy\", process_name = _config.tunModeItem.proxyProcess };\n                    configStr = configStr.Replace(\"$ruleProxyProcess$\", \",\" + Utils.ToJson(process));\n                }\n\n                var final = new { outbound = \"direct\", inbound = \"tun-in\" };\n                configStr = configStr.Replace(\"$ruleFinally$\", \",\" + Utils.ToJson(final));\n            }\n            configStr = configStr.Replace(\"$ruleDirectIPs$\", \"\");\n            configStr = configStr.Replace(\"$ruleDirectProcess$\", \"\");\n            configStr = configStr.Replace(\"$ruleProxyIPs$\", \"\");\n            configStr = configStr.Replace(\"$ruleProxyProcess$\", \"\");\n            configStr = configStr.Replace(\"$ruleFinally$\", \"\");\n\n            File.WriteAllText(Utils.GetConfigPath(_tunConfigName), configStr);\n\n            return true;\n        }\n\n        private void routingDirectExe(out List<string> lstDnsExe, out List<string> lstDirectExe)\n        {\n            lstDnsExe = new();\n            lstDirectExe = new();\n            var coreInfos = LazyConfig.Instance.GetCoreInfos();\n            foreach (var it in coreInfos)\n            {\n                if (it.coreType == ECoreType.v2rayN)\n                {\n                    continue;\n                }\n                foreach (var it2 in it.coreExes)\n                {\n                    if (!lstDnsExe.Contains(it2) && it.coreType != ECoreType.sing_box)\n                    {\n                        lstDnsExe.Add($\"{it2}.exe\");\n                    }\n\n                    if (!lstDirectExe.Contains(it2))\n                    {\n                        lstDirectExe.Add($\"{it2}.exe\");\n                    }\n                }\n            }\n        }\n\n        private void CoreStop()\n        {\n            try\n            {\n                _isRunning = false;\n                if (_process != null)\n                {\n                    KillProcess(_process);\n                    _process.Dispose();\n                    _process = null;\n                    _needRestart = true;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private string CoreFindexe()\n        {\n            string fileName = string.Empty;\n            foreach (string name in coreInfo.coreExes)\n            {\n                string vName = $\"{name}.exe\";\n                vName = Utils.GetBinPath(vName, coreInfo.coreType);\n                if (File.Exists(vName))\n                {\n                    fileName = vName;\n                    break;\n                }\n            }\n            if (Utils.IsNullOrEmpty(fileName))\n            {\n                string msg = string.Format(ResUI.NotFoundCore, Utils.GetBinPath(\"\", coreInfo.coreType), string.Join(\", \", coreInfo.coreExes.ToArray()), coreInfo.coreUrl);\n                Utils.SaveLog(msg);\n            }\n            return fileName;\n        }\n\n        private void CoreStart()\n        {\n            try\n            {\n                string fileName = CoreFindexe();\n                if (Utils.IsNullOrEmpty(fileName))\n                {\n                    return;\n                }\n                var showWindow = _config.tunModeItem.showWindow;\n                Process p = new()\n                {\n                    StartInfo = new ProcessStartInfo\n                    {\n                        FileName = fileName,\n                        Arguments = $\"run -c \\\"{Utils.GetConfigPath(_tunConfigName)}\\\"\",\n                        WorkingDirectory = Utils.GetConfigPath(),\n                        UseShellExecute = showWindow,\n                        CreateNoWindow = !showWindow,\n                        //RedirectStandardError = !showWindow,\n                        Verb = \"runas\",\n                    }\n                };\n                p.Start();\n                _process = p;\n                _isRunning = true;\n                if (p.WaitForExit(1000))\n                {\n                    //if (showWindow)\n                    //{\n                    throw new Exception(\"start tun mode fail\");\n                    //}\n                    //else\n                    //{\n                    //    throw new Exception(p.StandardError.ReadToEnd());\n                    //}\n                }\n\n                Global.processJob.AddProcess(p.Handle);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private void KillProcess(Process p)\n        {\n            try\n            {\n                p.CloseMainWindow();\n                p.WaitForExit(100);\n                if (!p.HasExited)\n                {\n                    p.Kill();\n                    p.WaitForExit(100);\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private int CoreStartTest()\n        {\n            Utils.SaveLog(\"Tun mode configuration file test start\");\n            try\n            {\n                string fileName = CoreFindexe();\n                if (fileName == \"\")\n                {\n                    return -1;\n                }\n                Process p = new Process\n                {\n                    StartInfo = new ProcessStartInfo\n                    {\n                        FileName = fileName,\n                        Arguments = $\"run -c \\\"{Utils.GetConfigPath(_tunConfigName)}\\\"\",\n                        WorkingDirectory = Utils.GetConfigPath(),\n                        UseShellExecute = false,\n                        CreateNoWindow = true,\n                        RedirectStandardError = true,\n                        Verb = \"runas\",\n                    }\n                };\n                p.Start();\n                if (p.WaitForExit(2000))\n                {\n                    throw new Exception(p.StandardError.ReadToEnd());\n                }\n                KillProcess(p);\n                return 0;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                return -1;\n            }\n            finally\n            {\n                Utils.SaveLog(\"Tun mode configuration file test end\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Handler/UpdateHandle.cs",
    "content": "﻿using DynamicData;\nusing Splat;\nusing System.Diagnostics;\nusing System.IO;\nusing System.Runtime.InteropServices;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Handler\n{\n    internal class UpdateHandle\n    {\n        private Action<bool, string> _updateFunc;\n        private Config _config;\n\n        public event EventHandler<ResultEventArgs> AbsoluteCompleted;\n\n        public class ResultEventArgs : EventArgs\n        {\n            public bool Success;\n            public string Msg;\n\n            public ResultEventArgs(bool success, string msg)\n            {\n                Success = success;\n                Msg = msg;\n            }\n        }\n\n        public void CheckUpdateGuiN(Config config, Action<bool, string> update, bool preRelease)\n        {\n            _config = config;\n            _updateFunc = update;\n            var url = string.Empty;\n\n            DownloadHandle downloadHandle = new();\n            downloadHandle.UpdateCompleted += (sender2, args) =>\n            {\n                if (args.Success)\n                {\n                    _updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);\n\n                    try\n                    {\n                        string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));\n                        fileName = Utils.UrlEncode(fileName);\n                        Process process = new()\n                        {\n                            StartInfo = new ProcessStartInfo\n                            {\n                                FileName = Global.UpgradeProgramExePath,\n                                Arguments = $\"\\\"{fileName}\\\"\",\n                                WorkingDirectory = Utils.StartupPath()\n                            }\n                        };\n                        process.Start();\n                        if (process.Id > 0)\n                        {\n                            _updateFunc(true, \"\");\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        _updateFunc(false, ex.Message);\n                    }\n                }\n                else\n                {\n                    _updateFunc(false, args.Msg);\n                }\n            };\n            downloadHandle.Error += (sender2, args) =>\n            {\n                _updateFunc(false, args.GetException().Message);\n            };\n            AbsoluteCompleted += (sender2, args) =>\n            {\n                if (args.Success)\n                {\n                    _updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, \"HiddifyN\"));\n\n                    url = args.Msg;\n                    _ = askToDownload(downloadHandle, url, true);\n                }\n                else\n                {\n                    Locator.Current.GetService<NoticeHandler>()?.Enqueue(args.Msg);\n                    _updateFunc(false, args.Msg);\n                }\n            };\n            _updateFunc(false, string.Format(ResUI.MsgStartUpdating, \"HiddifyN\"));\n            CheckUpdateAsync(ECoreType.v2rayN, preRelease);\n        }\n\n        public void CheckUpdateCore(ECoreType type, Config config, Action<bool, string> update, bool preRelease)\n        {\n            _config = config;\n            _updateFunc = update;\n            var url = string.Empty;\n\n            DownloadHandle downloadHandle = new();\n            downloadHandle.UpdateCompleted += (sender2, args) =>\n            {\n                if (args.Success)\n                {\n                    _updateFunc(false, ResUI.MsgDownloadV2rayCoreSuccessfully);\n                    _updateFunc(false, ResUI.MsgUnpacking);\n\n                    try\n                    {\n                        _updateFunc(true, url);\n                    }\n                    catch (Exception ex)\n                    {\n                        _updateFunc(false, ex.Message);\n                    }\n                }\n                else\n                {\n                    _updateFunc(false, args.Msg);\n                }\n            };\n            downloadHandle.Error += (sender2, args) =>\n            {\n                _updateFunc(true, args.GetException().Message);\n            };\n\n            AbsoluteCompleted += (sender2, args) =>\n            {\n                if (args.Success)\n                {\n                    _updateFunc(false, string.Format(ResUI.MsgParsingSuccessfully, \"Core\"));\n                    url = args.Msg;\n                    _ = askToDownload(downloadHandle, url, true);\n                }\n                else\n                {\n                    Locator.Current.GetService<NoticeHandler>()?.Enqueue(args.Msg);\n                    _updateFunc(false, args.Msg);\n                }\n            };\n            _updateFunc(false, string.Format(ResUI.MsgStartUpdating, \"Core\"));\n            CheckUpdateAsync(type, preRelease);\n        }\n\n        public void UpdateSubscriptionProcess(Config config, string subId, bool blProxy, Action<bool, string> update)\n        {\n            _config = config;\n            _updateFunc = update;\n\n            _updateFunc(false, ResUI.MsgUpdateSubscriptionStart);\n            var subItem = LazyConfig.Instance.SubItems();\n\n            if (subItem == null || subItem.Count <= 0)\n            {\n                _updateFunc(false, ResUI.MsgNoValidSubscription);\n                return;\n            }\n\n            bool anySubUpdated = false;\n\n            Task.Run(async () =>\n            {\n                for (int i = 0; i< subItem.Count; i++)\n                {\n                    var item = subItem[i];\n                    if (item.enabled == false)\n                    {\n                        continue;\n                    }\n                    if (!Utils.IsNullOrEmpty(subId) && item.id != subId)\n                    {\n                        continue;\n                    }\n\n                    string id = item.id.TrimEx();\n                    string url = item.url.TrimEx();\n                    string userAgent = item.userAgent.TrimEx();\n                    string hashCode = $\"{item.remarks}->\";\n                    if (Utils.IsNullOrEmpty(id) || Utils.IsNullOrEmpty(url) || (!Utils.IsNullOrEmpty(subId) && item.id != subId))\n                    {\n                        //_updateFunc(false, $\"{hashCode}{ResUI.MsgNoValidSubscription}\");\n                        continue;\n                    }\n                    if (item.enabled == false)\n                    {\n                        _updateFunc(false, $\"{hashCode}{ResUI.MsgSkipSubscriptionUpdate}\");\n                        continue;\n                    }\n\n                    var downloadHandle = new DownloadHandle();\n                    downloadHandle.Error += (sender2, args) =>\n                    {\n                        _updateFunc(false, $\"{hashCode}{args.GetException().Message}\");\n                    };\n\n                    _updateFunc(false, $\"{hashCode}{ResUI.MsgStartGettingSubscriptions}\");\n\n                    //one url\n                    url = Utils.GetPunycode(url);\n                    //convert\n                    if (!Utils.IsNullOrEmpty(item.convertTarget))\n                    {\n                        var subConvertUrl = string.IsNullOrEmpty(config.constItem.subConvertUrl) ? Global.SubConvertUrls.FirstOrDefault() : config.constItem.subConvertUrl;\n                        url = string.Format(subConvertUrl!, Utils.UrlEncode(url));\n                        if (!url.Contains(\"target=\"))\n                        {\n                            url += string.Format(\"&target={0}\", item.convertTarget);\n                        }\n                        if (!url.Contains(\"config=\"))\n                        {\n                            url += string.Format(\"&config={0}\", Global.SubConvertConfig.FirstOrDefault());\n                        }\n                    }\n                    var result = await downloadHandle.TryDownloadString(url, blProxy, userAgent);\n                    if (blProxy && Utils.IsNullOrEmpty(result))\n                    {\n                        result = await downloadHandle.TryDownloadString(url, false, userAgent);\n                    }\n\n                    //more url\n                    if (Utils.IsNullOrEmpty(item.convertTarget) && !Utils.IsNullOrEmpty(item.moreUrl.TrimEx()))\n                    {\n                        if (!Utils.IsNullOrEmpty(result) && Utils.IsBase64String(result))\n                        {\n                            result = Utils.Base64Decode(result);\n                        }\n\n                        var lstUrl = new List<string>\n                        {\n                            item.moreUrl.TrimEx().Split(\",\")\n                        };\n                        foreach (var it in lstUrl)\n                        {\n                            var url2 = Utils.GetPunycode(it);\n                            if (Utils.IsNullOrEmpty(url2))\n                            {\n                                continue;\n                            }\n\n                            var result2 = await downloadHandle.TryDownloadString(url2, blProxy, userAgent);\n                            if (blProxy && Utils.IsNullOrEmpty(result2))\n                            {\n                                result2 = await downloadHandle.TryDownloadString(url2, false, userAgent);\n                            }\n                            if (!Utils.IsNullOrEmpty(result2))\n                            {\n                                if (Utils.IsBase64String(result2))\n                                {\n                                    result += Utils.Base64Decode(result2);\n                                }\n                                else\n                                {\n                                    result += result2;\n                                }\n                            }\n                        }\n                    }\n\n                    if (Utils.IsNullOrEmpty(result))\n                    {\n                        _updateFunc(false, $\"{hashCode}{ResUI.MsgSubscriptionDecodingFailed}\");\n                    }\n                    else\n                    {\n                        _updateFunc(false, $\"{hashCode}{ResUI.MsgGetSubscriptionSuccessfully}\");\n                        if (result!.Length < 99)\n                        {\n                            _updateFunc(false, $\"{hashCode}{result}\");\n                        }\n\n                        int ret = ConfigHandler.AddBatchServers(ref config, result, id, true);\n                        if (ret <= 0)\n                        {\n                            Utils.SaveLog(\"FailedImportSubscription\");\n                            Utils.SaveLog(result);\n                        }\n                        else\n                        {\n                            ConfigHandler.SortServers(ref _config, id, \"\", true);\n                            anySubUpdated = true;\n                        }\n                        _updateFunc(false,\n                            ret > 0\n                                ? $\"{hashCode}{ResUI.MsgUpdateSubscriptionEnd}\"\n                                : $\"{hashCode}{ResUI.MsgFailedImportSubscription}\");\n                    }\n                    _updateFunc(false, \"-------------------------------------------------------\");\n                }\n\n                if (!anySubUpdated) \n                {\n                    _updateFunc(false, $\"{ResUI.MsgNothingUpdated}\");\n                }\n                _updateFunc(true, $\"{ResUI.MsgUpdateSubscriptionEnd}\");\n            });\n        }\n\n        public void UpdateGeoFileAll(Config config, Action<bool, string> update)\n        {\n            Task.Run(async () =>\n            {\n                await UpdateGeoFile(\"geosite\", _config, update);\n                await UpdateGeoFile(\"geoip\", _config, update);\n\n                await UpdateGeoFile4Singbox(\"geosite\", _config, update);\n                await UpdateGeoFile4Singbox(\"geoip\", _config, update);\n            });\n        }\n\n        public void RunAvailabilityCheck(Action<bool, string> update)\n        {\n            Task.Run(async () =>\n            {\n                var time = await (new DownloadHandle()).RunAvailabilityCheck(null);\n\n                update(false, string.Format(ResUI.TestMeOutput, time));\n            });\n        }\n\n        #region private\n\n        private async void CheckUpdateAsync(ECoreType type, bool preRelease)\n        {\n            try\n            {\n                var coreInfo = LazyConfig.Instance.GetCoreInfo(type);\n                string url = coreInfo.coreReleaseApiUrl;\n\n                var result = await (new DownloadHandle()).DownloadStringAsync(url, true, \"\");\n                if (!Utils.IsNullOrEmpty(result))\n                {\n                    responseHandler(type, result, preRelease);\n                }\n                else\n                {\n                    Utils.SaveLog(\"StatusCode error: \" + url);\n                    return;\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                _updateFunc(false, ex.Message);\n            }\n        }\n\n        /// <summary>\n        /// 获取V2RayCore版本\n        /// </summary>\n        private string getCoreVersion(ECoreType type)\n        {\n            try\n            {\n                var coreInfo = LazyConfig.Instance.GetCoreInfo(type);\n                string filePath = string.Empty;\n                foreach (string name in coreInfo.coreExes)\n                {\n                    string vName = $\"{name}.exe\";\n                    vName = Utils.GetBinPath(vName, coreInfo.coreType);\n                    if (File.Exists(vName))\n                    {\n                        filePath = vName;\n                        break;\n                    }\n                }\n\n                if (!File.Exists(filePath))\n                {\n                    string msg = string.Format(ResUI.NotFoundCore, @\"\", \"\", \"\");\n                    //ShowMsg(true, msg);\n                    return \"\";\n                }\n\n                using Process p = new();\n                p.StartInfo.FileName = filePath;\n                p.StartInfo.Arguments = coreInfo.versionArg;\n                p.StartInfo.WorkingDirectory = Utils.StartupPath();\n                p.StartInfo.UseShellExecute = false;\n                p.StartInfo.RedirectStandardOutput = true;\n                p.StartInfo.CreateNoWindow = true;\n                p.StartInfo.StandardOutputEncoding = Encoding.UTF8;\n                p.Start();\n                p.WaitForExit(5000);\n                string echo = p.StandardOutput.ReadToEnd();\n                string version = string.Empty;\n                switch (type)\n                {\n                    case ECoreType.v2fly:\n                    case ECoreType.SagerNet:\n                    case ECoreType.Xray:\n                    case ECoreType.v2fly_v5:\n                        version = Regex.Match(echo, $\"{coreInfo.match} ([0-9.]+) \\\\(\").Groups[1].Value;\n                        break;\n\n                    case ECoreType.clash:\n                    case ECoreType.clash_meta:\n                        version = Regex.Match(echo, $\"v[0-9.]+\").Groups[0].Value;\n                        break;\n\n                    case ECoreType.sing_box:\n                        version = Regex.Match(echo, $\"([0-9.]+)\").Groups[1].Value;\n                        break;\n                }\n                return version;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                _updateFunc(false, ex.Message);\n                return \"\";\n            }\n        }\n\n        private void responseHandler(ECoreType type, string gitHubReleaseApi, bool preRelease)\n        {\n            try\n            {\n                var gitHubReleases = Utils.FromJson<List<GitHubRelease>>(gitHubReleaseApi);\n                string version;\n                if (preRelease)\n                {\n                    version = gitHubReleases!.First().TagName;\n                }\n                else\n                {\n                    version = gitHubReleases!.First(r => r.Prerelease == false).TagName;\n                }\n                var coreInfo = LazyConfig.Instance.GetCoreInfo(type);\n\n                string curVersion;\n                string message;\n                string url;\n                switch (type)\n                {\n                    case ECoreType.v2fly:\n                    case ECoreType.SagerNet:\n                    case ECoreType.Xray:\n                    case ECoreType.v2fly_v5:\n                        {\n                            curVersion = \"v\" + getCoreVersion(type);\n                            message = string.Format(ResUI.IsLatestCore, curVersion);\n                            string osBit = \"64\";\n                            switch (RuntimeInformation.ProcessArchitecture)\n                            {\n                                case Architecture.Arm64:\n                                    osBit = \"arm64-v8a\";\n                                    break;\n\n                                case Architecture.X86:\n                                    osBit = \"32\";\n                                    break;\n\n                                default:\n                                    osBit = \"64\";\n                                    break;\n                            }\n\n                            url = string.Format(coreInfo.coreDownloadUrl64, version, osBit);\n                            break;\n                        }\n                    case ECoreType.clash:\n                    case ECoreType.clash_meta:\n                        {\n                            curVersion = getCoreVersion(type);\n                            message = string.Format(ResUI.IsLatestCore, curVersion);\n                            switch (RuntimeInformation.ProcessArchitecture)\n                            {\n                                case Architecture.Arm64:\n                                    url = coreInfo.coreDownloadUrlArm64;\n                                    break;\n\n                                case Architecture.X86:\n                                    url = coreInfo.coreDownloadUrl32;\n                                    break;\n\n                                default:\n                                    url = coreInfo.coreDownloadUrl64;\n                                    break;\n                            }\n                            url = string.Format(url, version);\n                            break;\n                        }\n                    case ECoreType.sing_box:\n                        {\n                            curVersion = \"v\" + getCoreVersion(type);\n                            message = string.Format(ResUI.IsLatestCore, curVersion);\n                            switch (RuntimeInformation.ProcessArchitecture)\n                            {\n                                case Architecture.Arm64:\n                                    url = coreInfo.coreDownloadUrlArm64;\n                                    break;\n\n                                case Architecture.X86:\n                                    url = coreInfo.coreDownloadUrl32;\n                                    break;\n\n                                default:\n                                    url = coreInfo.coreDownloadUrl64;\n                                    break;\n                            }\n                            url = string.Format(url, version, version.Replace(\"v\", \"\"));\n                            break;\n                        }\n                    case ECoreType.v2rayN:\n                        {\n                            curVersion = FileVersionInfo.GetVersionInfo(Utils.GetExePath()).FileVersion.ToString();\n                            message = string.Format(ResUI.IsLatestN, curVersion);\n                            switch (RuntimeInformation.ProcessArchitecture)\n                            {\n                                case Architecture.Arm64:\n                                    url = string.Format(coreInfo.coreDownloadUrlArm64, version);\n                                    break;\n\n                                case Architecture.X86:\n                                    url = string.Format(coreInfo.coreDownloadUrl32, version);\n                                    break;\n\n                                default:\n                                    url = string.Format(coreInfo.coreDownloadUrl64, version);\n                                    break;\n                            }\n                            break;\n                        }\n                    default:\n                        throw new ArgumentException(\"Type\");\n                }\n\n                if (type == ECoreType.v2rayN)\n                {\n                    decimal.TryParse(curVersion, out decimal decCur);\n                    decimal.TryParse(version, out decimal dec);\n                    if (decCur >= dec)\n                    {\n                        AbsoluteCompleted?.Invoke(this, new ResultEventArgs(false, message));\n                        return;\n                    }\n                }\n\n                if (curVersion == version)\n                {\n                    AbsoluteCompleted?.Invoke(this, new ResultEventArgs(false, message));\n                    return;\n                }\n\n                AbsoluteCompleted?.Invoke(this, new ResultEventArgs(true, url));\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                _updateFunc(false, ex.Message);\n            }\n        }\n\n        private async Task askToDownload(DownloadHandle downloadHandle, string url, bool blAsk)\n        {\n            bool blDownload = false;\n            if (blAsk)\n            {\n                if (UI.ShowYesNo(string.Format(ResUI.DownloadYesNo, url)) == MessageBoxResult.Yes)\n                {\n                    blDownload = true;\n                }\n            }\n            else\n            {\n                blDownload = true;\n            }\n            if (blDownload)\n            {\n                await downloadHandle.DownloadFileAsync(url, true, 600);\n            }\n        }\n\n        private async Task UpdateGeoFile(string geoName, Config config, Action<bool, string> update)\n        {\n            _config = config;\n            _updateFunc = update;\n            var url = string.Format(Global.geoUrl, geoName);\n\n            DownloadHandle downloadHandle = new();\n            downloadHandle.UpdateCompleted += (sender2, args) =>\n            {\n                if (args.Success)\n                {\n                    _updateFunc(false, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, geoName));\n\n                    try\n                    {\n                        string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));\n                        if (File.Exists(fileName))\n                        {\n                            //Global.coreTypes.ForEach(it =>\n                            //{\n                            //    string targetPath = Utils.GetBinPath($\"{geoName}.dat\", (ECoreType)Enum.Parse(typeof(ECoreType), it));\n                            //    File.Copy(fileName, targetPath, true);\n                            //});\n                            string targetPath = Utils.GetBinPath($\"{geoName}.dat\");\n                            File.Copy(fileName, targetPath, true);\n\n                            File.Delete(fileName);\n                            //_updateFunc(true, \"\");\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        _updateFunc(false, ex.Message);\n                    }\n                }\n                else\n                {\n                    _updateFunc(false, args.Msg);\n                }\n            };\n            downloadHandle.Error += (sender2, args) =>\n            {\n                _updateFunc(false, args.GetException().Message);\n            };\n            await askToDownload(downloadHandle, url, false);\n        }\n\n        private async Task UpdateGeoFile4Singbox(string geoName, Config config, Action<bool, string> update)\n        {\n            _config = config;\n            _updateFunc = update;\n            var url = string.Format(Global.singboxGeoUrl, geoName);\n\n            DownloadHandle downloadHandle = new();\n            downloadHandle.UpdateCompleted += (sender2, args) =>\n            {\n                if (args.Success)\n                {\n                    _updateFunc(false, string.Format(ResUI.MsgDownloadGeoFileSuccessfully, geoName));\n\n                    try\n                    {\n                        string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(url));\n                        if (File.Exists(fileName))\n                        {\n                            string targetPath = Utils.GetConfigPath($\"{geoName}.db\");\n                            File.Copy(fileName, targetPath, true);\n\n                            File.Delete(fileName);\n                        }\n                    }\n                    catch (Exception ex)\n                    {\n                        _updateFunc(false, ex.Message);\n                    }\n                }\n                else\n                {\n                    _updateFunc(false, args.Msg);\n                }\n            };\n            downloadHandle.Error += (sender2, args) =>\n            {\n                _updateFunc(false, args.GetException().Message);\n            };\n            await askToDownload(downloadHandle, url, false);\n        }\n\n        #endregion private\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/BalancerItem.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    public class BalancerItem\n    {\n        public string tag { get; set; }\n        public string[] selector { get; set; }\n\n        public BalancerStrategyItem strategy { get; set; }\n        public BalancerStrategySettings optimalSettings { get; set; }\n\n    }\n    [Serializable]\n    public class BalancerStrategyItem\n    {\n        public string type { get; set; }\n        public BalancerStrategySettings settings { get; set; }\n    }\n\n    \n    public interface BalancerStrategySettings{}\n\n    [Serializable]\n    public class OptimalBalancerStrategySetting: BalancerStrategySettings\n    {\n        public int timeout { get; set; } = 10000;\n        public int interval { get; set; } = 30000;\n        public string url { get; set; } = \"https://about.google\";\n        public int count { get; set; } = 3;\n        public bool accept_little_diff { get; set; } = true;\n        public bool load_balancing { get; set; } = false;\n        public double diff_percent { get; set; } = 0.5;\n\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ComboItem.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public class ComboItem\n    {\n        public string ID\n        {\n            get; set;\n        }\n\n        public string Text\n        {\n            get; set;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/Config.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    /// <summary>\n    /// 本软件配置文件实体类\n    /// </summary>\n    [Serializable]\n    public class Config\n    {\n        #region property\n\n        public string indexId { get; set; }\n        public string subIndexId { get; set; }\n        public ESysProxyType sysProxyType { get; set; }\n        public string systemProxyExceptions { get; set; }\n        public string systemProxyAdvancedProtocol { get; set; }\n\n        #endregion property\n\n        #region other entities\n\n        public CoreBasicItem coreBasicItem { get; set; }\n        public TunModeItem tunModeItem { get; set; }\n        public KcpItem kcpItem { get; set; }\n        public GrpcItem grpcItem { get; set; }\n        public RoutingBasicItem routingBasicItem { get; set; }\n        public GUIItem guiItem { get; set; }\n        public UIItem uiItem { get; set; }\n        public ConstItem constItem { get; set; }\n        public SpeedTestItem speedTestItem { get; set; }\n        public List<InItem> inbound { get; set; }\n        public List<KeyEventItem> globalHotkeys { get; set; }\n        public List<CoreTypeItem> coreTypeItem { get; set; }\n\n        #endregion other entities\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ConfigItems.cs",
    "content": "﻿using System.Windows.Input;\n\nnamespace v2rayN.Mode\n{\n    [Serializable]\n    public class CoreBasicItem\n    {\n        /// <summary>\n        /// 允许日志\n        /// </summary>\n        public bool logEnabled { get; set; }\n\n        /// <summary>\n        /// 日志等级\n        /// </summary>\n        public string loglevel { get; set; }\n\n        /// <summary>\n        /// 允许Mux多路复用\n        /// </summary>\n        public bool muxEnabled { get; set; }\n\n        /// <summary>\n        /// 是否允许不安全连接\n        /// </summary>\n        public bool defAllowInsecure { get; set; }\n\n        public string defFingerprint { get; set; }\n\n        /// <summary>\n        /// 默认用户代理\n        /// </summary>\n        public string defUserAgent { get; set; }\n    }\n\n    [Serializable]\n    public class InItem\n    {\n        public int localPort { get; set; }\n\n        public string protocol { get; set; }\n\n        public bool udpEnabled { get; set; }\n\n        public bool sniffingEnabled { get; set; } = true;\n        public bool routeOnly { get; set; }\n\n        public bool allowLANConn { get; set; }\n\n        public bool newPort4LAN { get; set; }\n\n        public string user { get; set; }\n\n        public string pass { get; set; }\n    }\n\n    [Serializable]\n    public class KcpItem\n    {\n        public int mtu { get; set; }\n\n        public int tti { get; set; }\n\n        public int uplinkCapacity { get; set; }\n\n        public int downlinkCapacity { get; set; }\n\n        public bool congestion { get; set; }\n\n        public int readBufferSize { get; set; }\n\n        public int writeBufferSize { get; set; }\n    }\n\n    [Serializable]\n    public class GrpcItem\n    {\n        public int idle_timeout { get; set; }\n        public int health_check_timeout { get; set; }\n        public bool permit_without_stream { get; set; }\n        public int initial_windows_size { get; set; }\n    }\n\n    [Serializable]\n    public class GUIItem\n    {\n        public bool autoRun { get; set; }\n\n        public bool enableStatistics { get; set; }\n\n        public int statisticsFreshRate { get; set; }\n\n        public bool keepOlderDedupl { get; set; }\n\n        public bool ignoreGeoUpdateCore { get; set; } = true;\n\n        public int autoUpdateInterval { get; set; } = 10;\n\n        public bool checkPreReleaseUpdate { get; set; } = false;\n\n        public bool enableSecurityProtocolTls13 { get; set; } = true;\n\n        public int trayMenuServersLimit { get; set; } = 20;\n        \n\n        public bool enableHWA { get; set; } = false;\n\n        public bool enableLog { get; set; } = true;\n    }\n\n    [Serializable]\n    public class UIItem\n    {\n        public bool enableAutoAdjustMainLvColWidth { get; set; }\n        public double mainWidth { get; set; }\n        public double mainHeight { get; set; }\n        public double mainGirdHeight1 { get; set; }\n        public double mainGirdHeight2 { get; set; }\n        public bool colorModeDark { get; set; } = true;\n        public string? colorPrimaryName { get; set; }\n        public string currentLanguage { get; set; }\n        public string currentFontFamily { get; set; }\n        public int currentFontSize { get; set; } = 14;\n        public bool enableDragDropSort { get; set; }\n        public bool doubleClick2Activate { get; set; }\n        public bool autoHideStartup { get; set; } = false;\n        public string mainMsgFilter { get; set; }\n        public bool showTrayTip { get; set; }\n        public List<ColumnItem> mainColumnItem { get; set; }\n    }\n\n    [Serializable]\n    public class ConstItem\n    {\n        public string defIEProxyExceptions { get; set; }\n        public string subConvertUrl { get; set; } = string.Empty;\n    }\n\n    [Serializable]\n    public class KeyEventItem\n    {\n        public EGlobalHotkey eGlobalHotkey { get; set; }\n\n        public bool Alt { get; set; }\n\n        public bool Control { get; set; }\n\n        public bool Shift { get; set; }\n\n        public Key? KeyCode { get; set; }\n    }\n\n    [Serializable]\n    public class CoreTypeItem\n    {\n        public EConfigType configType { get; set; }\n\n        public ECoreType coreType { get; set; }\n    }\n\n    [Serializable]\n    public class TunModeItem\n    {\n        public bool enableTun { get; set; }\n        public bool showWindow { get; set; }\n        public bool enabledLog { get; set; }\n        public bool strictRoute { get; set; }\n        public string stack { get; set; }\n        public int mtu { get; set; }\n        public string customTemplate { get; set; }\n        public bool bypassMode { get; set; } = true;\n        public List<string> directIP { get; set; }\n        public List<string> directProcess { get; set; }\n        public string directDNS { get; set; }\n        public List<string> proxyIP { get; set; }\n        public List<string> proxyProcess { get; set; }\n        public string proxyDNS { get; set; }\n    }\n\n    [Serializable]\n    public class SpeedTestItem\n    {\n        public int speedTestTimeout { get; set; }\n        public string speedTestUrl { get; set; }\n        public string speedPingTestUrl { get; set; }\n    }\n\n    [Serializable]\n    public class RoutingBasicItem\n    {\n        /// <summary>\n        /// 域名解析策略\n        /// </summary>\n        public string domainStrategy { get; set; }\n        public string domainStrategy4Singbox { get; set; }\n\n        public string domainMatcher { get; set; }\n        public string routingIndexId { get; set; }\n        public bool enableRoutingAdvanced { get; set; }\n    }\n\n    [Serializable]\n    public class ColumnItem\n    {\n        public string Name { get; set; }\n        public int Width { get; set; }\n        public int Index { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ConfigOld.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    public class ConfigOld\n    {\n        #region property\n\n        /// <summary>\n        /// 允许日志\n        /// </summary>\n        public bool logEnabled\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 日志等级\n        /// </summary>\n        public string loglevel\n        {\n            get; set;\n        }\n\n        public string indexId\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 允许Mux多路复用\n        /// </summary>\n        public bool muxEnabled\n        {\n            get; set;\n        }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public ESysProxyType sysProxyType\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 启用实时网速和流量统计\n        /// </summary>\n        public bool enableStatistics\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 去重时优先保留较旧（顶部）节点\n        /// </summary>\n        public bool keepOlderDedupl\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 视图刷新率\n        /// </summary>\n        public int statisticsFreshRate\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 自定义远程DNS\n        /// </summary>\n        public string remoteDNS\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// Outbound Freedom domainStrategy\n        /// </summary>\n        public string domainStrategy4Freedom\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 是否允许不安全连接\n        /// </summary>\n        public bool defAllowInsecure\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 域名解析策略\n        /// </summary>\n        public string domainStrategy\n        {\n            get; set;\n        }\n\n        public string domainMatcher\n        {\n            get; set;\n        }\n\n        public int routingIndex\n        {\n            get; set;\n        }\n\n        public bool enableRoutingAdvanced\n        {\n            get; set;\n        }\n\n        public bool ignoreGeoUpdateCore\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// systemProxyExceptions\n        /// </summary>\n        public string systemProxyExceptions\n        {\n            get; set;\n        }\n\n        public string systemProxyAdvancedProtocol { get; set; }\n\n        public int autoUpdateInterval { get; set; } = 0;\n\n        public int autoUpdateSubInterval { get; set; } = 0;\n\n        public bool checkPreReleaseUpdate { get; set; } = false;\n\n        public bool enableSecurityProtocolTls13 { get; set; } = true;\n\n        public int trayMenuServersLimit { get; set; }\n\n        #endregion property\n\n        #region other entities\n\n        /// <summary>\n        /// 本地监听\n        /// </summary>\n        public List<InItem> inbound\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// vmess服务器信息\n        /// </summary>\n        public List<VmessItem> vmess\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// KcpItem\n        /// </summary>\n        public KcpItem kcpItem\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 订阅\n        /// </summary>\n        public List<SubItem> subItem\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// UI\n        /// </summary>\n        public UIItem uiItem\n        {\n            get; set;\n        }\n\n        public List<RoutingItemOld> routings\n        {\n            get; set;\n        }\n\n        public ConstItem constItem\n        {\n            get; set;\n        }\n\n        public List<KeyEventItem> globalHotkeys\n        {\n            get; set;\n        }\n\n        public List<CoreTypeItem> coreTypeItem\n        {\n            get; set;\n        }\n\n        #endregion other entities\n    }\n\n    [Serializable]\n    public class VmessItem\n    {\n        public VmessItem()\n        {\n            indexId = string.Empty;\n            configType = EConfigType.VMess;\n            configVersion = 2;\n            sort = 0;\n            address = string.Empty;\n            port = 0;\n            id = string.Empty;\n            alterId = 0;\n            security = string.Empty;\n            network = string.Empty;\n            remarks = string.Empty;\n            headerType = string.Empty;\n            requestHost = string.Empty;\n            path = string.Empty;\n            streamSecurity = string.Empty;\n            allowInsecure = string.Empty;\n            testResult = string.Empty;\n            subid = string.Empty;\n            flow = string.Empty;\n            groupId = string.Empty;\n        }\n\n        public string indexId\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// config type(1=normal,2=custom)\n        /// </summary>\n        public EConfigType configType\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 版本(现在=2)\n        /// </summary>\n        public int configVersion\n        {\n            get; set;\n        }\n\n        public int sort\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 远程服务器地址\n        /// </summary>\n        public string address\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 远程服务器端口\n        /// </summary>\n        public int port\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 远程服务器ID\n        /// </summary>\n        public string id\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 远程服务器额外ID\n        /// </summary>\n        public int alterId\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 本地安全策略\n        /// </summary>\n        public string security\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// tcp,kcp,ws,h2,quic\n        /// </summary>\n        public string network\n        {\n            get; set;\n        }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string remarks\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 伪装类型\n        /// </summary>\n        public string headerType\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 伪装的域名\n        /// </summary>\n        public string requestHost\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// ws h2 path\n        /// </summary>\n        public string path\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 传输层安全\n        /// </summary>\n        public string streamSecurity\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// 是否允许不安全连接（用于客户端）\n        /// </summary>\n        public string allowInsecure\n        {\n            get; set;\n        }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string testResult\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// SubItem id\n        /// </summary>\n        public string subid\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// VLESS flow\n        /// </summary>\n        public string flow\n        {\n            get; set;\n        }\n\n        /// <summary>\n        /// tls sni\n        /// </summary>\n        public string sni\n        {\n            get; set;\n        }\n\n        public string groupId\n        {\n            get; set;\n        } = string.Empty;\n\n        public ECoreType? coreType\n        {\n            get; set;\n        }\n\n        public int preSocksPort\n        {\n            get; set;\n        }\n\n        public string fingerprint { get; set; }\n    }\n\n    [Serializable]\n    public class RoutingItemOld\n    {\n        public string remarks\n        {\n            get; set;\n        }\n\n        public string url\n        {\n            get; set;\n        }\n\n        public List<RulesItem> rules\n        {\n            get; set;\n        }\n\n        public bool enabled { get; set; } = true;\n\n        public bool locked\n        {\n            get; set;\n        }\n\n        public string customIcon\n        {\n            get; set;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/CoreInfo.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    public class CoreInfo\n    {\n        public ECoreType coreType { get; set; }\n\n        public List<string> coreExes { get; set; }\n\n        public string arguments { get; set; }\n\n        public string coreUrl { get; set; }\n\n        public string coreReleaseApiUrl { get; set; }\n\n        public string coreDownloadUrl32 { get; set; }\n\n        public string coreDownloadUrl64 { get; set; }\n\n        public string coreDownloadUrlArm64 { get; set; }\n\n        public string match { get; set; }\n        public string versionArg { get; set; }\n\n        public bool redirectInfo { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/DNSItem.cs",
    "content": "﻿using SQLite;\n\nnamespace v2rayN.Mode\n{\n    [Serializable]\n    public class DNSItem\n    {\n        [PrimaryKey]\n        public string id { get; set; }\n\n        public string remarks { get; set; }\n        public bool enabled { get; set; } = true;\n        public ECoreType coreType { get; set; }\n        public string? normalDNS { get; set; }\n        public string? directDNS { get; set; }\n        public string? proxyDNS { get; set; }\n        public string? domainStrategy4Freedom { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/EConfigType.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum EConfigType\n    {\n        VMess = 1,\n        Custom = 2,\n        Shadowsocks = 3,\n        Socks = 4,\n        VLESS = 5,\n        Trojan = 6,\n        LowestPing = 101,\n        LoadBalance=102,\n        Usage = 103,\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ECoreType.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum ECoreType\n    {\n        v2fly = 1,\n        Xray = 2,\n        SagerNet = 3,\n        v2fly_v5 = 4,\n        clash = 11,\n        clash_meta = 12,\n        hysteria = 21,\n        naiveproxy = 22,\n        tuic = 23,\n        sing_box = 24,\n        v2rayN = 99\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/EGlobalHotkey.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum EGlobalHotkey\n    {\n        ShowForm = 0,\n        SystemProxyClear = 1,\n        SystemProxySet = 2,\n        SystemProxyUnchanged = 3,\n        SystemProxyPac = 4,\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/EMove.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum EMove\n    {\n        Top = 1,\n        Up = 2,\n        Down = 3,\n        Bottom = 4,\n        Position = 5\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/EServerColName.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum EServerColName\n    {\n        def = 0,\n        configType,\n        remarks,\n        address,\n        port,\n        security,\n        network,\n        streamSecurity,\n        subRemarks,\n        delayVal,\n        speedVal,\n\n        todayDown,\n        todayUp,\n        totalDown,\n        totalUp\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ESpeedActionType.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum ESpeedActionType\n    {\n        Ping,\n        Tcping,\n        Realping,\n        Speedtest,\n        Mixedtest\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ESysProxyType.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum ESysProxyType\n    {\n        ForcedClear = 0,\n        ForcedChange = 1,\n        Unchanged = 2,\n        Pac = 3\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/EViewAction.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public enum EViewAction\n    {\n        AdjustMainLvColWidth,\n        ProfilesFocus\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/GitHubRelease.cs",
    "content": "﻿using Newtonsoft.Json;\n\nnamespace v2rayN.Mode\n{\n    public class GitHubReleaseAsset\n    {\n        [JsonProperty(\"url\")] public string Url { get; set; }\n\n        [JsonProperty(\"id\")] public int Id { get; set; }\n\n        [JsonProperty(\"node_id\")] public string NodeId { get; set; }\n\n        [JsonProperty(\"name\")] public string Name { get; set; }\n\n        [JsonProperty(\"label\")] public object Label { get; set; }\n\n        [JsonProperty(\"content_type\")] public string ContentType { get; set; }\n\n        [JsonProperty(\"state\")] public string State { get; set; }\n\n        [JsonProperty(\"size\")] public int Size { get; set; }\n\n        [JsonProperty(\"download_count\")] public int DownloadCount { get; set; }\n\n        [JsonProperty(\"created_at\")] public DateTime CreatedAt { get; set; }\n\n        [JsonProperty(\"updated_at\")] public DateTime UpdatedAt { get; set; }\n\n        [JsonProperty(\"browser_download_url\")] public string BrowserDownloadUrl { get; set; }\n    }\n\n    public class GitHubRelease\n    {\n        [JsonProperty(\"url\")] public string Url { get; set; }\n\n        [JsonProperty(\"assets_url\")] public string AssetsUrl { get; set; }\n\n        [JsonProperty(\"upload_url\")] public string UploadUrl { get; set; }\n\n        [JsonProperty(\"html_url\")] public string HtmlUrl { get; set; }\n\n        [JsonProperty(\"id\")] public int Id { get; set; }\n\n        [JsonProperty(\"node_id\")] public string NodeId { get; set; }\n\n        [JsonProperty(\"tag_name\")] public string TagName { get; set; }\n\n        [JsonProperty(\"target_commitish\")] public string TargetCommitish { get; set; }\n\n        [JsonProperty(\"name\")] public string Name { get; set; }\n\n        [JsonProperty(\"draft\")] public bool Draft { get; set; }\n\n        [JsonProperty(\"prerelease\")] public bool Prerelease { get; set; }\n\n        [JsonProperty(\"created_at\")] public DateTime CreatedAt { get; set; }\n\n        [JsonProperty(\"published_at\")] public DateTime PublishedAt { get; set; }\n\n        [JsonProperty(\"assets\")] public List<GitHubReleaseAsset> Assets { get; set; }\n\n        [JsonProperty(\"tarball_url\")] public string TarballUrl { get; set; }\n\n        [JsonProperty(\"zipball_url\")] public string ZipballUrl { get; set; }\n\n        [JsonProperty(\"body\")] public string Body { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/HiddifyEnums.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing v2rayN.Resx;\nusing System.Resources;\nusing v2rayN.Mode;\n\nnamespace v2rayN.Mode\n{\n    internal class HiddifyEnums\n    {\n    }\n    public enum RoutingEnum\n    {\n        All,\n        Blocked,\n        BypassNotblocked\n    }\n    public enum ProxyModeEnum : int\n    {\n        [LocalizedDescription(\"HomeProxyAuto\", typeof(ResUI))]\n        Smart,\n        [LocalizedDescription(\"HomeProxyLoadBalance\", typeof(ResUI))]\n        Loadbalance,\n        [LocalizedDescription(\"HomeProxyManual\", typeof(ResUI))]\n        Manual\n    \n\n    }\n}\n\n    public class LocalizedDescriptionAttribute : DescriptionAttribute\n    {\n        private readonly string _resourceName;\n        private readonly Type _resourceType;\n\n        public LocalizedDescriptionAttribute(string resourceName, Type resourceType)\n        {\n            _resourceName = resourceName;\n            _resourceType = resourceType;\n        }\n\n        public override string Description\n        {\n            get\n            {\n                ResourceManager rm = new ResourceManager(_resourceType);\n                return rm.GetString(_resourceName);\n            }\n        }\n\n    \n}\n\n\npublic static class ProxyModeEnumExtensions\n{\n    public static string ToLocalizedDescriptionString(this ProxyModeEnum value)\n    {\n        var fieldInfo = value.GetType().GetField(value.ToString());\n        var attributes = fieldInfo.GetCustomAttributes(typeof(LocalizedDescriptionAttribute), false) as LocalizedDescriptionAttribute[];\n        return attributes?.Length > 0 ? attributes[0].Description : value.ToString();\n    }\n\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ProfileExItem.cs",
    "content": "﻿using SQLite;\n\nnamespace v2rayN.Mode\n{\n    [Serializable]\n    public class ProfileExItem\n    {\n        [PrimaryKey]\n        public string indexId { get; set; }\n\n        public int delay { get; set; }\n        public decimal speed { get; set; }\n        public int sort { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ProfileItem.cs",
    "content": "﻿using SQLite;\nusing v2rayN.Base;\n\nnamespace v2rayN.Mode\n{\n    [Serializable]\n    public class ProfileItem\n    {\n        public ProfileItem()\n        {\n            indexId = string.Empty;\n            configType = EConfigType.VMess;\n            configVersion = 2;\n            address = string.Empty;\n            port = 0;\n            id = string.Empty;\n            alterId = 0;\n            security = string.Empty;\n            network = string.Empty;\n            remarks = string.Empty;\n            headerType = string.Empty;\n            requestHost = string.Empty;\n            path = string.Empty;\n            streamSecurity = string.Empty;\n            allowInsecure = string.Empty;\n            subid = string.Empty;\n            flow = string.Empty;\n        }\n\n        #region function\n\n        public string GetSummary()\n        {\n            string summary = string.Format(\"[{0}] \", (configType).ToString());\n            string[] arrAddr = address.Split('.');\n            string addr;\n            if (arrAddr.Length > 2)\n            {\n                addr = $\"{arrAddr[0]}***{arrAddr[arrAddr.Length - 1]}\";\n            }\n            else if (arrAddr.Length > 1)\n            {\n                addr = $\"***{arrAddr[arrAddr.Length - 1]}\";\n            }\n            else\n            {\n                addr = address;\n            }\n            switch (configType)\n            {\n                case EConfigType.VMess:\n                case EConfigType.Shadowsocks:\n                case EConfigType.Socks:\n                case EConfigType.VLESS:\n                case EConfigType.Trojan:\n                    summary += string.Format(\"{0}({1}:{2})\", remarks, addr, port);\n                    break;\n\n                default:\n                    summary += string.Format(\"{0}\", remarks);\n                    break;\n            }\n            return summary;\n        }\n\n        public List<string> GetAlpn()\n        {\n            if (Utils.IsNullOrEmpty(alpn))\n            {\n                return null;\n            }\n            else\n            {\n                return Utils.String2List(alpn);\n            }\n        }\n\n        public string GetNetwork()\n        {\n            if (Utils.IsNullOrEmpty(network) || !Global.networks.Contains(network))\n            {\n                return Global.DefaultNetwork;\n            }\n            return network.TrimEx();\n        }\n\n        #endregion function\n\n        [PrimaryKey]\n        public string indexId { get; set; }\n\n        /// <summary>\n        /// config type(1=normal,2=custom)\n        /// </summary>\n        public EConfigType configType { get; set; }\n\n        /// <summary>\n        /// 版本(现在=2)\n        /// </summary>\n        public int configVersion { get; set; }\n\n        /// <summary>\n        /// 远程服务器地址\n        /// </summary>\n        public string address { get; set; }\n\n        /// <summary>\n        /// 远程服务器端口\n        /// </summary>\n        public int port { get; set; }\n\n        /// <summary>\n        /// 远程服务器ID\n        /// </summary>\n        public string id { get; set; }\n\n        /// <summary>\n        /// 远程服务器额外ID\n        /// </summary>\n        public int alterId { get; set; }\n\n        /// <summary>\n        /// 本地安全策略\n        /// </summary>\n        public string security { get; set; }\n\n        /// <summary>\n        /// tcp,kcp,ws,h2,quic\n        /// </summary>\n        public string network { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string remarks { get; set; }\n\n        /// <summary>\n        /// 伪装类型\n        /// </summary>\n        public string headerType { get; set; }\n\n        /// <summary>\n        /// 伪装的域名\n        /// </summary>\n        public string requestHost { get; set; }\n\n        /// <summary>\n        /// ws h2 path\n        /// </summary>\n        public string path { get; set; }\n        public string fragment { get; set; }//hiddify\n\n        /// <summary>\n        /// 传输层安全\n        /// </summary>\n        public string streamSecurity { get; set; }\n\n        /// <summary>\n        /// 是否允许不安全连接（用于客户端）\n        /// </summary>\n        public string allowInsecure { get; set; }\n\n        /// <summary>\n        /// SubItem id\n        /// </summary>\n        public string subid { get; set; }\n\n        public bool isSub { get; set; } = true;\n\n        /// <summary>\n        /// VLESS flow\n        /// </summary>\n        public string flow { get; set; }\n\n        /// <summary>\n        /// tls sni\n        /// </summary>\n        public string sni { get; set; }\n\n        /// <summary>\n        /// tls alpn\n        /// </summary>\n        public string alpn { get; set; } = string.Empty;\n\n        public ECoreType? coreType { get; set; }\n\n        public int preSocksPort { get; set; }\n\n        public string fingerprint { get; set; }\n\n        public bool displayLog { get; set; } = true;\n        public string publicKey { get; set; }\n        public string shortId { get; set; }\n        public string spiderX { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ProfileItemModel.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    public class ProfileItemModel : ProfileItem\n    {\n        public bool isActive { get; set; }\n        public string subRemarks { get; set; }\n        public int delay { get; set; }\n        public decimal speed { get; set; }\n        public int sort { get; set; }\n        public string delayVal { get; set; }\n        public string speedVal { get; set; }\n        public string todayUp { get; set; }\n        public string todayDown { get; set; }\n        public string totalUp { get; set; }\n        public string totalDown { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ProxyMode.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace v2rayN.Mode\n{\n    public class ProxyMode\n    {\n        public int id { get; set; }\n        public string remark { get; set; }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Mode/RoutingItem.cs",
    "content": "﻿using SQLite;\n\nnamespace v2rayN.Mode\n{\n    [Serializable]\n    public class RoutingItem\n    {\n        [PrimaryKey]\n        public string id { get; set; }\n\n        public string remarks { get; set; }\n        public string url { get; set; }\n        public string ruleSet { get; set; }\n        public int ruleNum { get; set; }\n        public bool enabled { get; set; } = true;\n        public bool locked { get; set; }\n        public string customIcon { get; set; }\n        public string domainStrategy { get; set; }\n        public string domainStrategy4Singbox { get; set; }\n        public int sort { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/RoutingItemModel.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    public class RoutingItemModel : RoutingItem\n    {\n        public bool isActive { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/RulesItem.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    public class RulesItem\n    {\n        public string id { get; set; }\n        public string type { get; set; }\n\n        public string port { get; set; }\n\n        public List<string> inboundTag { get; set; }\n\n        public string outboundTag { get; set; }\n        public string balancerTag { get; set; }\n\n        public List<string> ip { get; set; }\n\n        public List<string> domain { get; set; }\n\n        public List<string> protocol { get; set; }\n\n        public bool enabled { get; set; } = true;\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/RulesItemModel.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    public class RulesItemModel : RulesItem\n    {\n        public string inboundTags { get; set; }\n\n        public string ips { get; set; }\n\n        public string domains { get; set; }\n\n        public string protocols { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ServerSpeedItem.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    internal class ServerSpeedItem : ServerStatItem\n    {\n        public long proxyUp\n        {\n            get; set;\n        }\n\n        public long proxyDown\n        {\n            get; set;\n        }\n\n        public long directUp\n        {\n            get; set;\n        }\n\n        public long directDown\n        {\n            get; set;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ServerStatItem.cs",
    "content": "﻿using SQLite;\n\nnamespace v2rayN.Mode\n{\n    [Serializable]\n    public class ServerStatItem\n    {\n        [PrimaryKey]\n        public string indexId\n        {\n            get; set;\n        }\n\n        public long totalUp\n        {\n            get; set;\n        }\n\n        public long totalDown\n        {\n            get; set;\n        }\n\n        public long todayUp\n        {\n            get; set;\n        }\n\n        public long todayDown\n        {\n            get; set;\n        }\n\n        public long dateNow\n        {\n            get; set;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/ServerTestItem.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    [Serializable]\n    internal class ServerTestItem\n    {\n        public string indexId { get; set; }\n        public string address { get; set; }\n        public int port { get; set; }\n        public EConfigType configType { get; set; }\n        public bool allowTest { get; set; }\n        public int delay { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/SingboxConfig.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public class SingboxConfig\n    {\n        public Log4Sbox log { get; set; }\n        public object dns { get; set; }\n        public List<Inbound4Sbox> inbounds { get; set; }\n        public List<Outbound4Sbox> outbounds { get; set; }\n        public Route4Sbox route { get; set; }\n        public Experimental4Sbox experimental { get; set; }\n    }\n\n    public class Log4Sbox\n    {\n        public bool? disabled { get; set; }\n        public string level { get; set; }\n        public string output { get; set; }\n        public bool timestamp { get; set; }\n    }\n\n    public class Dns4Sbox\n    {\n        public List<Server4Sbox> servers { get; set; }\n        public List<Rule4Sbox> rules { get; set; }\n    }\n\n    public class Route4Sbox\n    {\n        public bool? auto_detect_interface { get; set; }\n        public List<Rule4Sbox> rules { get; set; }\n    }\n\n    [Serializable]\n    public class Rule4Sbox\n    {\n        public string outbound { get; set; }\n        public string server { get; set; }\n        public bool? disable_cache { get; set; }\n        public List<string>? inbound { get; set; }\n        public List<string>? protocol { get; set; }\n        public string type { get; set; }\n        public string mode { get; set; }\n        public string network { get; set; }\n        public List<int>? port { get; set; }\n        public List<string>? port_range { get; set; }\n        public List<string>? geosite { get; set; }\n        public List<string>? domain { get; set; }\n        public List<string>? domain_suffix { get; set; }\n        public List<string>? domain_keyword { get; set; }\n        public List<string>? domain_regex { get; set; }\n        public List<string>? geoip { get; set; }\n        public List<string>? ip_cidr { get; set; }\n        public List<string>? source_ip_cidr { get; set; }\n\n        public List<string>? process_name { get; set; }\n    }\n\n    [Serializable]\n    public class Inbound4Sbox\n    {\n        public string type { get; set; }\n        public string tag { get; set; }\n        public string listen { get; set; }\n        public int? listen_port { get; set; }\n        public string? domain_strategy { get; set; }\n        public string interface_name { get; set; }\n        public string inet4_address { get; set; }\n        public string inet6_address { get; set; }\n        public int? mtu { get; set; }\n        public bool? auto_route { get; set; }\n        public bool? strict_route { get; set; }\n        public bool? endpoint_independent_nat { get; set; }\n        public string? stack { get; set; }\n        public bool? sniff { get; set; }\n        public bool? sniff_override_destination { get; set; }\n        public List<User4Sbox> users { get; set; }\n    }\n\n    public class User4Sbox\n    {\n        public string username { get; set; }\n        public string password { get; set; }\n    }\n\n    public class Outbound4Sbox\n    {\n        public string type { get; set; }\n        public string tag { get; set; }\n        public string server { get; set; }\n        public int? server_port { get; set; }\n        public string uuid { get; set; }\n        public string security { get; set; }\n        public int? alter_id { get; set; }\n        public string flow { get; set; }\n        public int? up_mbps { get; set; }\n        public int? down_mbps { get; set; }\n        public string auth_str { get; set; }\n        public int? recv_window_conn { get; set; }\n        public int? recv_window { get; set; }\n        public bool? disable_mtu_discovery { get; set; }\n        public string detour { get; set; }\n        public string method { get; set; }\n        public string username { get; set; }\n        public string password { get; set; }\n        public string? version { get; set; }\n        public string? network { get; set; }\n        public string packet_encoding { get; set; }\n        public Tls4Sbox tls { get; set; }\n        public Multiplex4Sbox multiplex { get; set; }\n        public Transport4Sbox transport { get; set; }\n    }\n\n    public class Tls4Sbox\n    {\n        public bool enabled { get; set; }\n        public string server_name { get; set; }\n        public bool? insecure { get; set; }\n        public List<string> alpn { get; set; }\n        public Utls4Sbox utls { get; set; }\n        public Reality4Sbox reality { get; set; }\n    }\n\n    public class Multiplex4Sbox\n    {\n        public bool enabled { get; set; }\n        public string protocol { get; set; }\n        public int max_connections { get; set; }\n        public int min_streams { get; set; }\n        public int max_streams { get; set; }\n    }\n\n    public class Utls4Sbox\n    {\n        public bool enabled { get; set; }\n        public string fingerprint { get; set; }\n    }\n\n    public class Reality4Sbox\n    {\n        public bool enabled { get; set; }\n        public string public_key { get; set; }\n        public string short_id { get; set; }\n    }\n\n    public class Transport4Sbox\n    {\n        public string type { get; set; }\n        public List<string>? host { get; set; }\n        public string? path { get; set; }\n        public string service_name { get; set; }\n        public string idle_timeout { get; set; }\n        public string ping_timeout { get; set; }\n        public bool? permit_without_stream { get; set; }\n    }\n\n    public class Server4Sbox\n    {\n        public string tag { get; set; }\n        public string address { get; set; }\n        public string address_resolver { get; set; }\n        public string strategy { get; set; }\n        public string detour { get; set; }\n    }\n\n    public class Experimental4Sbox\n    {\n        public V2ray_Api4Sbox v2ray_api { get; set; }\n    }\n\n    public class V2ray_Api4Sbox\n    {\n        public string listen { get; set; }\n        public Stats4Sbox stats { get; set; }\n    }\n\n    public class Stats4Sbox\n    {\n        public bool enabled { get; set; }\n        public List<string>? inbounds { get; set; }\n        public List<string>? outbounds { get; set; }\n        public List<string>? users { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/SsSIP008.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    public class SsSIP008\n    {\n        public List<SsServer> servers { get; set; }\n    }\n\n    [Serializable]\n    public class SsServer\n    {\n        public string remarks { get; set; }\n        public string server { get; set; }\n        public string server_port { get; set; }\n        public string method { get; set; }\n        public string password { get; set; }\n        public string plugin { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/SubItem.cs",
    "content": "﻿\nusing SQLite;\nusing System.Windows;\nnamespace v2rayN.Mode\n{\n    [Serializable]\n    public class SubItem\n    {\n        [PrimaryKey]\n        public string id { get; set; }\n\n        public string remarks { get; set; }\n\n        public string url { get; set; }\n\n        public string moreUrl { get; set; }\n\n        public bool enabled { get; set; } = true;\n\n        public string userAgent { get; set; } = string.Empty;\n\n        public int sort { get; set; }\n\n        public string? filter { get; set; }\n        public long upload { get; set; }\n        public long download { get; set; }\n        public long total { get; set; }\n        public long usage { get { return (download + upload); } set { } }\n        \n        public long expireDate { get; set; }\n        public int remaningExpireDays { get; set; }\n        public int UsedDataGB { get; set; }\n        public int TotalDataGB { get; set; }\n        public string? profileWebPageUrl { get; set; }\n\n        public int profileUpdateInterval { get; set; }\n\n        public long updateTime { get; set; }\n\n        public string? convertTarget { get; set; }\n        public Visibility sub_info_visible { get { return TotalDataGB>0?Visibility.Visible:Visibility.Collapsed;} }\n        //public Visibility sub_info_visible { get { return Visibility.Collapsed; } }\n        public double UploadMegaBytes()\n        {\n            return GetJustThreeDigitOfaNumber(this.upload/1024/1024);\n        }\n        public double DownloadMegaBytes()\n        {\n            return GetJustThreeDigitOfaNumber(this.download/1024 / 1024);\n        }\n        public double TotalMegaBytes()\n        {\n            return GetJustThreeDigitOfaNumber(this.total/1024 / 1024);\n        }\n\n        public double UploadGigaBytes()\n        {\n            return GetJustThreeDigitOfaNumber(this.upload / 1024 / 1024/1024);\n        }\n        public double DownloadGigaBytes()\n        {\n            return GetJustThreeDigitOfaNumber(this.download / 1024 / 1024 / 1024);\n        }\n        public int TotalDataGigaBytes()\n        {\n            return (int)((this.total / 1024 / 1024 / 1024));\n        }\n        public int UsedDataGigaBytes()\n        {\n            return (int)(this.download + this.upload) / 1024 / 1024 / 1024;\n        }\n        public double DownloadAndUploadTotalGigaBytes()\n        {\n            return GetJustThreeDigitOfaNumber((this.download + this.upload) / 1024 / 1024 / 1024);\n        }\n        public DateTime ExpireToDate()\n        {\n            return Utils.EpochToDate(this.expireDate);\n        }\n\n        public int DaysLeftToExpire()\n        {\n            return this.ExpireToDate().Subtract(DateTime.Now).Days;\n        }\n\n        private double GetJustThreeDigitOfaNumber(double num)\n        {\n            string strNum = \"\";\n            int counter = 0;\n            foreach (var n in num.ToString().ToCharArray())\n            {\n                if (counter == 3)\n                {\n                    break;\n                }\n                strNum += n;\n                counter++;\n            }\n\n            return double.Parse(strNum);\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/SubscriptionInfo.cs",
    "content": "﻿\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace v2rayN.Mode\n{\n    public class SubscriptionInfo\n    {\n        public long Upload { get; set; }\n        public long Download { get; set; }\n        public long Total { get; set; }\n        public long ExpireDate { get; set; }\n        public string? ProfileWebPageUrl { get; set; }\n        public string? ProfileTitle { get; set; }\n        public int ProfileUpdateInterval { get; set; }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Mode/SysproxyConfig.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    internal class SysproxyConfig\n    {\n        public bool UserSettingsRecorded;\n        public string Flags;\n        public string ProxyServer;\n        public string BypassList;\n        public string PacUrl;\n\n        public SysproxyConfig()\n        {\n            UserSettingsRecorded = false;\n            Flags = \"1\";\n            ProxyServer = \"\";\n            BypassList = \"\";\n            PacUrl = \"\";\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/V2rayConfig.cs",
    "content": "﻿using Newtonsoft.Json;\nusing System.Windows.Documents;\n\nnamespace v2rayN.Mode\n{\n    /// <summary>\n    /// v2ray配置文件实体类\n    /// 例子SampleConfig.txt\n    /// </summary>\n    public class V2rayConfig\n    {\n        /// <summary>\n        /// 日志配置\n        /// </summary>\n        public Log log { get; set; }\n\n        /// <summary>\n        /// 传入连接配置\n        /// </summary>\n        public List<Inbounds> inbounds { get; set; }\n\n        /// <summary>\n        /// 传出连接配置\n        /// </summary>\n        public List<Outbounds> outbounds { get; set; }\n\n        /// <summary>\n        /// 统计需要， 空对象\n        /// </summary>\n        public Stats stats { get; set; }\n\n        /// </summary>\n        public API api { get; set; }\n\n        /// </summary>\n        public Policy policy;\n\n        /// <summary>\n        /// DNS 配置\n        /// </summary>\n        public object dns { get; set; }\n\n        /// <summary>\n        /// 路由配置\n        /// </summary>\n        public Routing routing { get; set; }\n        public Observatory observatory { get; set; }\n    }\n\n    public class Observatory\n    {\n        public String[] subjectSelector { get; set; }\n        public String probeURL { get; set; }\n        public String probeInterval { get; set; }\n\n\n    };\n    public class Stats { };\n\n    public class API\n    {\n        public string tag { get; set; }\n        public List<string> services { get; set; }\n    }\n\n    public class Policy\n    {\n        public SystemPolicy system;\n    }\n\n    public class SystemPolicy\n    {\n        public bool statsOutboundUplink;\n        public bool statsOutboundDownlink;\n    }\n\n    public class Log\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string access { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string error { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string loglevel { get; set; }\n    }\n\n    public class Inbounds\n    {\n        public string tag { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int port { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string listen { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string protocol { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Sniffing sniffing { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Inboundsettings settings { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public StreamSettings streamSettings { get; set; }\n    }\n\n    public class Inboundsettings\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string auth { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public bool udp { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string ip { get; set; }\n\n        /// <summary>\n        /// api 使用\n        /// </summary>\n        public string address { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public List<UsersItem> clients { get; set; }\n\n        /// <summary>\n        /// VLESS\n        /// </summary>\n        public string decryption { get; set; }\n\n        public bool allowTransparent { get; set; }\n\n        public List<AccountsItem> accounts { get; set; }\n    }\n\n    public class UsersItem\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string id { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int alterId { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string email { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string security { get; set; }\n\n        /// <summary>\n        /// VLESS\n        /// </summary>\n        public string encryption { get; set; }\n\n        /// <summary>\n        /// VLESS\n        /// </summary>\n        public string flow { get; set; }\n    }\n\n    public class Sniffing\n    {\n        public bool enabled { get; set; }\n        public List<string> destOverride { get; set; }\n        public bool routeOnly { get; set; }\n    }\n\n    public class Outbounds\n    {\n        /// <summary>\n        /// 默认值agentout\n        /// </summary>\n        public string tag { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string protocol { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Outboundsettings settings { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public StreamSettings streamSettings { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Mux mux { get; set; }\n    }\n\n    public class Outboundsettings\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public List<VnextItem> vnext { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public List<ServersItem> servers { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Response response { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string domainStrategy { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int? userLevel { get; set; }\n    }\n\n    public class VnextItem\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string address { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int port { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public List<UsersItem> users { get; set; }\n    }\n\n    public class ServersItem\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string email { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string address { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string method { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public bool ota { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string password { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int port { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int level { get; set; }\n\n        /// <summary>\n        /// trojan\n        /// </summary>\n        public string flow { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public List<SocksUsersItem> users { get; set; }\n    }\n\n    public class SocksUsersItem\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string user { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string pass { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int level { get; set; }\n    }\n\n    public class Mux\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public bool enabled { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int concurrency { get; set; }\n    }\n\n    public class Response\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string type { get; set; }\n    }\n\n    public class Dns\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public List<string> servers { get; set; }\n    }\n\n    public class Routing\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string domainStrategy { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string domainMatcher { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public List<RulesItem> rules { get; set; }\n        /// <summary>\n        /// \n        /// </summary>\n        public List<BalancerItem> balancers { get; set; }=new List<BalancerItem>();\n    }\n\n\n    public class StreamSettings\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string network { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string security { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public TlsSettings tlsSettings { get; set; }\n\n        /// <summary>\n        /// Tcp传输额外设置\n        /// </summary>\n        public TcpSettings tcpSettings { get; set; }\n\n        /// <summary>\n        /// Kcp传输额外设置\n        /// </summary>\n        public KcpSettings kcpSettings { get; set; }\n\n        /// <summary>\n        /// ws传输额外设置\n        /// </summary>\n        public WsSettings wsSettings { get; set; }\n\n        /// <summary>\n        /// h2传输额外设置\n        /// </summary>\n        public HttpSettings httpSettings { get; set; }\n\n        /// <summary>\n        /// QUIC\n        /// </summary>\n        public QuicSettings quicSettings { get; set; }\n\n        /// <summary>\n        /// VLESS only\n        /// </summary>\n        public TlsSettings realitySettings { get; set; }\n\n        /// <summary>\n        /// grpc\n        /// </summary>\n        public GrpcSettings grpcSettings { get; set; }\n    }\n\n    public class TlsSettings\n    {\n        /// <summary>\n        /// 是否允许不安全连接（用于客户端）\n        /// </summary>\n        public bool? allowInsecure { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string? serverName { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public List<string>? alpn { get; set; }\n\n        public string? fingerprint { get; set; }\n\n        public bool? show { get; set; } = false;\n        public string? publicKey { get; set; }\n        public string? shortId { get; set; }\n        public string? spiderX { get; set; }\n        public string? minVersion { get; set; }//hiddify\n\n    }\n\n    public class TcpSettings\n    {\n        /// <summary>\n        /// 数据包头部伪装设置\n        /// </summary>\n        public Header header { get; set; }\n    }\n\n    public class Header\n    {\n        /// <summary>\n        /// 伪装\n        /// </summary>\n        public string type { get; set; }\n\n        /// <summary>\n        /// 结构复杂，直接存起来\n        /// </summary>\n        public object request { get; set; }\n\n        /// <summary>\n        /// 结构复杂，直接存起来\n        /// </summary>\n        public object response { get; set; }\n    }\n\n    public class KcpSettings\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public int mtu { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int tti { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int uplinkCapacity { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int downlinkCapacity { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public bool congestion { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int readBufferSize { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public int writeBufferSize { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Header header { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string seed { get; set; }\n    }\n\n    public class WsSettings\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string path { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Headers headers { get; set; }\n        public FragmentationConfig fragmentation { get; set; }\n    }\n    public class FragmentationConfig\n    {\n        public bool enabled { get; set; }=false;\n        public long fragmentationIntervalTimeout { get; set; } = 100;\n        public string strategy { get; set; } = \"random\";\n        public int maxChunkSize { get; set; } = 100;\n        public string sni { get; set; } = \"\";\n    }\n    public class Headers\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string Host { get; set; }\n\n        /// <summary>\n        /// 用户代理\n        /// </summary>\n        [JsonProperty(\"User-Agent\")]\n        public string UserAgent { get; set; }\n    }\n\n    public class HttpSettings\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string path { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public List<string> host { get; set; }\n    }\n\n    public class QuicSettings\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string security { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string key { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public Header header { get; set; }\n    }\n\n    public class GrpcSettings\n    {\n        public string serviceName { get; set; }\n        public bool multiMode { get; set; }\n        public int idle_timeout { get; set; }\n        public int health_check_timeout { get; set; }\n        public bool permit_without_stream { get; set; }\n        public int initial_windows_size { get; set; }\n    }\n\n    public class AccountsItem\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string user { get; set; }\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string pass { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/V2rayTcpRequest.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    /// <summary>\n    /// Tcp伪装http的Request，只要Host\n    /// </summary>\n    public class V2rayTcpRequest\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public RequestHeaders headers { get; set; }\n    }\n\n    public class RequestHeaders\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public List<string> Host { get; set; }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Mode/VmessQRCode.cs",
    "content": "﻿namespace v2rayN.Mode\n{\n    /// <summary>\n    /// https://github.com/2dust/v2rayN/wiki/\n    /// </summary>\n    [Serializable]\n    internal class VmessQRCode\n    {\n        /// <summary>\n        ///\n        /// </summary>\n        public string v { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string ps { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string add { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string port { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string id { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string aid { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string scy { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string net { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string type { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string host { get; set; } = string.Empty;\n\n        /// <summary>\n        ///\n        /// </summary>\n        public string path { get; set; } = string.Empty;\n\n        /// <summary>\n        /// TLS\n        /// </summary>\n        public string tls { get; set; } = string.Empty;\n\n        /// <summary>\n        /// TLS SNI\n        /// </summary>\n        public string sni { get; set; } = string.Empty;\n\n        /// <summary>\n        /// TLS alpn\n        /// </summary>\n        public string alpn { get; set; } = string.Empty;\n\n        /// <summary>\n        /// TLS fingerprint\n        /// </summary>\n        public string fp { get; set; } = string.Empty;\n        public string allowInsecure { get; set; } = string.Empty;\n\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Resx/Hiddify.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace v2rayN.Resx {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"17.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class Hiddify {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal Hiddify() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"v2rayN.Resx.Hiddify\", typeof(Hiddify).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Fragment.\n        /// </summary>\n        public static string Fragment {\n            get {\n                return ResourceManager.GetString(\"Fragment\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Resx/Hiddify.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=\"Fragment\" xml:space=\"preserve\">\n    <value>Fragment</value>\n  </data>\n</root>"
  },
  {
    "path": "v2rayN/v2rayN/Resx/ResUI.Designer.cs",
    "content": "﻿//------------------------------------------------------------------------------\n// <auto-generated>\n//     This code was generated by a tool.\n//     Runtime Version:4.0.30319.42000\n//\n//     Changes to this file may cause incorrect behavior and will be lost if\n//     the code is regenerated.\n// </auto-generated>\n//------------------------------------------------------------------------------\n\nnamespace v2rayN.Resx {\n    using System;\n    \n    \n    /// <summary>\n    ///   A strongly-typed resource class, for looking up localized strings, etc.\n    /// </summary>\n    // This class was auto-generated by the StronglyTypedResourceBuilder\n    // class via a tool like ResGen or Visual Studio.\n    // To add or remove a member, edit your .ResX file then rerun ResGen\n    // with the /str option, or rebuild your VS project.\n    [global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"System.Resources.Tools.StronglyTypedResourceBuilder\", \"17.0.0.0\")]\n    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]\n    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]\n    public class ResUI {\n        \n        private static global::System.Resources.ResourceManager resourceMan;\n        \n        private static global::System.Globalization.CultureInfo resourceCulture;\n        \n        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute(\"Microsoft.Performance\", \"CA1811:AvoidUncalledPrivateCode\")]\n        internal ResUI() {\n        }\n        \n        /// <summary>\n        ///   Returns the cached ResourceManager instance used by this class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Resources.ResourceManager ResourceManager {\n            get {\n                if (object.ReferenceEquals(resourceMan, null)) {\n                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager(\"v2rayN.Resx.ResUI\", typeof(ResUI).Assembly);\n                    resourceMan = temp;\n                }\n                return resourceMan;\n            }\n        }\n        \n        /// <summary>\n        ///   Overrides the current thread's CurrentUICulture property for all\n        ///   resource lookups using this strongly typed resource class.\n        /// </summary>\n        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]\n        public static global::System.Globalization.CultureInfo Culture {\n            get {\n                return resourceCulture;\n            }\n            set {\n                resourceCulture = value;\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Do you want to append rules? Choose yes to append, choose otherwise to replace.\n        /// </summary>\n        public static string AddBatchRoutingRulesYesNo {\n            get {\n                return ResourceManager.GetString(\"AddBatchRoutingRulesYesNo\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to All.\n        /// </summary>\n        public static string AllGroupServers {\n            get {\n                return ResourceManager.GetString(\"AllGroupServers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Batch export subscription to clipboard successfully.\n        /// </summary>\n        public static string BatchExportSubscriptionSuccessfully {\n            get {\n                return ResourceManager.GetString(\"BatchExportSubscriptionSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Batch export share URL to clipboard successfully.\n        /// </summary>\n        public static string BatchExportURLSuccessfully {\n            get {\n                return ResourceManager.GetString(\"BatchExportURLSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please check the server settings first.\n        /// </summary>\n        public static string CheckServerSettings {\n            get {\n                return ResourceManager.GetString(\"CheckServerSettings\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Invalid configuration format.\n        /// </summary>\n        public static string ConfigurationFormatIncorrect {\n            get {\n                return ResourceManager.GetString(\"ConfigurationFormatIncorrect\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Note that custom configuration relies entirely on your own configuration and does not work with all settings. If you want to use the system proxy, please modify the listening port manually..\n        /// </summary>\n        public static string CustomServerTips {\n            get {\n                return ResourceManager.GetString(\"CustomServerTips\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Downloading....\n        /// </summary>\n        public static string Downloading {\n            get {\n                return ResourceManager.GetString(\"Downloading\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Download.\n        /// </summary>\n        public static string downloadSpeed {\n            get {\n                return ResourceManager.GetString(\"downloadSpeed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Whether to download? {0}.\n        /// </summary>\n        public static string DownloadYesNo {\n            get {\n                return ResourceManager.GetString(\"DownloadYesNo\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to convert configuration file.\n        /// </summary>\n        public static string FailedConversionConfiguration {\n            get {\n                return ResourceManager.GetString(\"FailedConversionConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to generate default configuration file.\n        /// </summary>\n        public static string FailedGenDefaultConfiguration {\n            get {\n                return ResourceManager.GetString(\"FailedGenDefaultConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to  Failed to get the default configuration.\n        /// </summary>\n        public static string FailedGetDefaultConfiguration {\n            get {\n                return ResourceManager.GetString(\"FailedGetDefaultConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to import custom configuration server.\n        /// </summary>\n        public static string FailedImportedCustomServer {\n            get {\n                return ResourceManager.GetString(\"FailedImportedCustomServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to read configuration file.\n        /// </summary>\n        public static string FailedReadConfiguration {\n            get {\n                return ResourceManager.GetString(\"FailedReadConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to run Core, please see the log.\n        /// </summary>\n        public static string FailedToRunCore {\n            get {\n                return ResourceManager.GetString(\"FailedToRunCore\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the correct custom DNS.\n        /// </summary>\n        public static string FillCorrectDNSText {\n            get {\n                return ResourceManager.GetString(\"FillCorrectDNSText\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the correct format server port.\n        /// </summary>\n        public static string FillCorrectServerPort {\n            get {\n                return ResourceManager.GetString(\"FillCorrectServerPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the KCP parameters correctly.\n        /// </summary>\n        public static string FillKcpParameters {\n            get {\n                return ResourceManager.GetString(\"FillKcpParameters\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the local listening port.\n        /// </summary>\n        public static string FillLocalListeningPort {\n            get {\n                return ResourceManager.GetString(\"FillLocalListeningPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the password.\n        /// </summary>\n        public static string FillPassword {\n            get {\n                return ResourceManager.GetString(\"FillPassword\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the server address.\n        /// </summary>\n        public static string FillServerAddress {\n            get {\n                return ResourceManager.GetString(\"FillServerAddress\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please browse to import server configuration.\n        /// </summary>\n        public static string FillServerAddressCustom {\n            get {\n                return ResourceManager.GetString(\"FillServerAddressCustom\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the user ID.\n        /// </summary>\n        public static string FillUUID {\n            get {\n                return ResourceManager.GetString(\"FillUUID\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Transport.\n        /// </summary>\n        public static string GbTransport {\n            get {\n                return ResourceManager.GetString(\"GbTransport\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to  is not the correct client configuration file, please check.\n        /// </summary>\n        public static string IncorrectClientConfiguration {\n            get {\n                return ResourceManager.GetString(\"IncorrectClientConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to  is not the correct configuration, please check.\n        /// </summary>\n        public static string Incorrectconfiguration {\n            get {\n                return ResourceManager.GetString(\"Incorrectconfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to  is not the correct server configuration file, please check.\n        /// </summary>\n        public static string IncorrectServerConfiguration {\n            get {\n                return ResourceManager.GetString(\"IncorrectServerConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Initial Configuration.\n        /// </summary>\n        public static string InitialConfiguration {\n            get {\n                return ResourceManager.GetString(\"InitialConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} already up to date..\n        /// </summary>\n        public static string IsLatestCore {\n            get {\n                return ResourceManager.GetString(\"IsLatestCore\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} already up to date..\n        /// </summary>\n        public static string IsLatestN {\n            get {\n                return ResourceManager.GetString(\"IsLatestN\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to LAN.\n        /// </summary>\n        public static string LabLAN {\n            get {\n                return ResourceManager.GetString(\"LabLAN\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Local.\n        /// </summary>\n        public static string LabLocal {\n            get {\n                return ResourceManager.GetString(\"LabLocal\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Address.\n        /// </summary>\n        public static string LvAddress {\n            get {\n                return ResourceManager.GetString(\"LvAddress\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Automatic update interval(minutes) 的本地化字符串。\n        /// </summary>\n        public static string LvAutoUpdateInterval {\n            get {\n                return ResourceManager.GetString(\"LvAutoUpdateInterval\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Convert target type 的本地化字符串。\n        /// </summary>\n        public static string LvConvertTarget {\n            get {\n                return ResourceManager.GetString(\"LvConvertTarget\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Please leave blank if no conversion is required 的本地化字符串。\n        /// </summary>\n        public static string LvConvertTargetTip {\n            get {\n                return ResourceManager.GetString(\"LvConvertTargetTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Count 的本地化字符串。\n        /// </summary>\n        public static string LvCount {\n            get {\n                return ResourceManager.GetString(\"LvCount\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Custom Icon.\n        /// </summary>\n        public static string LvCustomIcon {\n            get {\n                return ResourceManager.GetString(\"LvCustomIcon\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enabled Update.\n        /// </summary>\n        public static string LvEnabled {\n            get {\n                return ResourceManager.GetString(\"LvEnabled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Security.\n        /// </summary>\n        public static string LvEncryptionMethod {\n            get {\n                return ResourceManager.GetString(\"LvEncryptionMethod\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remarks regular filter.\n        /// </summary>\n        public static string LvFilter {\n            get {\n                return ResourceManager.GetString(\"LvFilter\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 More urls, separated by commas;Subscription conversion will be invalid 的本地化字符串。\n        /// </summary>\n        public static string LvMoreUrl {\n            get {\n                return ResourceManager.GetString(\"LvMoreUrl\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Port 的本地化字符串。\n        /// </summary>\n        public static string LvPort {\n            get {\n                return ResourceManager.GetString(\"LvPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remarks.\n        /// </summary>\n        public static string LvRemarks {\n            get {\n                return ResourceManager.GetString(\"LvRemarks\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Type.\n        /// </summary>\n        public static string LvServiceType {\n            get {\n                return ResourceManager.GetString(\"LvServiceType\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sort.\n        /// </summary>\n        public static string LvSort {\n            get {\n                return ResourceManager.GetString(\"LvSort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Subs group.\n        /// </summary>\n        public static string LvSubscription {\n            get {\n                return ResourceManager.GetString(\"LvSubscription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Delay(ms).\n        /// </summary>\n        public static string LvTestDelay {\n            get {\n                return ResourceManager.GetString(\"LvTestDelay\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test Results.\n        /// </summary>\n        public static string LvTestResults {\n            get {\n                return ResourceManager.GetString(\"LvTestResults\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Speed(M/s).\n        /// </summary>\n        public static string LvTestSpeed {\n            get {\n                return ResourceManager.GetString(\"LvTestSpeed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to TLS.\n        /// </summary>\n        public static string LvTLS {\n            get {\n                return ResourceManager.GetString(\"LvTLS\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Download traffic today.\n        /// </summary>\n        public static string LvTodayDownloadDataAmount {\n            get {\n                return ResourceManager.GetString(\"LvTodayDownloadDataAmount\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Upload traffic today.\n        /// </summary>\n        public static string LvTodayUploadDataAmount {\n            get {\n                return ResourceManager.GetString(\"LvTodayUploadDataAmount\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Total download traffic.\n        /// </summary>\n        public static string LvTotalDownloadDataAmount {\n            get {\n                return ResourceManager.GetString(\"LvTotalDownloadDataAmount\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Total upload traffic.\n        /// </summary>\n        public static string LvTotalUploadDataAmount {\n            get {\n                return ResourceManager.GetString(\"LvTotalUploadDataAmount\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Transport.\n        /// </summary>\n        public static string LvTransportProtocol {\n            get {\n                return ResourceManager.GetString(\"LvTransportProtocol\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Url(Optional).\n        /// </summary>\n        public static string LvUrl {\n            get {\n                return ResourceManager.GetString(\"LvUrl\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to User Agent.\n        /// </summary>\n        public static string LvUserAgent {\n            get {\n                return ResourceManager.GetString(\"LvUserAgent\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Medium.\n        /// </summary>\n        public static string MediumFresh {\n            get {\n                return ResourceManager.GetString(\"MediumFresh\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add a custom configuration server.\n        /// </summary>\n        public static string menuAddCustomServer {\n            get {\n                return ResourceManager.GetString(\"menuAddCustomServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Import bulk URL from clipboard (Ctrl+V).\n        /// </summary>\n        public static string menuAddServerViaClipboard {\n            get {\n                return ResourceManager.GetString(\"menuAddServerViaClipboard\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Scan QR code on the screen (Ctrl+S).\n        /// </summary>\n        public static string menuAddServerViaScan {\n            get {\n                return ResourceManager.GetString(\"menuAddServerViaScan\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add [Shadowsocks] server.\n        /// </summary>\n        public static string menuAddShadowsocksServer {\n            get {\n                return ResourceManager.GetString(\"menuAddShadowsocksServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add [Socks] server.\n        /// </summary>\n        public static string menuAddSocksServer {\n            get {\n                return ResourceManager.GetString(\"menuAddSocksServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add [Trojan] server.\n        /// </summary>\n        public static string menuAddTrojanServer {\n            get {\n                return ResourceManager.GetString(\"menuAddTrojanServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add [VLESS] server.\n        /// </summary>\n        public static string menuAddVlessServer {\n            get {\n                return ResourceManager.GetString(\"menuAddVlessServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add [VMess] server.\n        /// </summary>\n        public static string menuAddVmessServer {\n            get {\n                return ResourceManager.GetString(\"menuAddVmessServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Check Update.\n        /// </summary>\n        public static string menuCheckUpdate {\n            get {\n                return ResourceManager.GetString(\"menuCheckUpdate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear all service statistics.\n        /// </summary>\n        public static string menuClearServerStatistics {\n            get {\n                return ResourceManager.GetString(\"menuClearServerStatistics\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Close.\n        /// </summary>\n        public static string menuClose {\n            get {\n                return ResourceManager.GetString(\"menuClose\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clone selected server.\n        /// </summary>\n        public static string menuCopyServer {\n            get {\n                return ResourceManager.GetString(\"menuCopyServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 DNS Settings 的本地化字符串。\n        /// </summary>\n        public static string menuDNSSetting {\n            get {\n                return ResourceManager.GetString(\"menuDNSSetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Edit Server (Ctrl+D) 的本地化字符串。\n        /// </summary>\n        public static string menuEditServer {\n            get {\n                return ResourceManager.GetString(\"menuEditServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Exit.\n        /// </summary>\n        public static string menuExit {\n            get {\n                return ResourceManager.GetString(\"menuExit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Export selected server for client configuration.\n        /// </summary>\n        public static string menuExport2ClientConfig {\n            get {\n                return ResourceManager.GetString(\"menuExport2ClientConfig\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Export selected server for server configuration.\n        /// </summary>\n        public static string menuExport2ServerConfig {\n            get {\n                return ResourceManager.GetString(\"menuExport2ServerConfig\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Export share URLs to clipboard (Ctrl+C).\n        /// </summary>\n        public static string menuExport2ShareUrl {\n            get {\n                return ResourceManager.GetString(\"menuExport2ShareUrl\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Export subscription (base64) share to clipboard.\n        /// </summary>\n        public static string menuExport2SubContent {\n            get {\n                return ResourceManager.GetString(\"menuExport2SubContent\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to GlobalHotkeySetting.\n        /// </summary>\n        public static string menuGlobalHotkeySetting {\n            get {\n                return ResourceManager.GetString(\"menuGlobalHotkeySetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Help.\n        /// </summary>\n        public static string menuHelp {\n            get {\n                return ResourceManager.GetString(\"menuHelp\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Import old config guiNConfig.\n        /// </summary>\n        public static string menuImportOldGuiConfig {\n            get {\n                return ResourceManager.GetString(\"menuImportOldGuiConfig\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Import Rules From Clipboard.\n        /// </summary>\n        public static string menuImportRulesFromClipboard {\n            get {\n                return ResourceManager.GetString(\"menuImportRulesFromClipboard\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Import Rules From File.\n        /// </summary>\n        public static string menuImportRulesFromFile {\n            get {\n                return ResourceManager.GetString(\"menuImportRulesFromFile\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Import Rules From Sub Url.\n        /// </summary>\n        public static string menuImportRulesFromUrl {\n            get {\n                return ResourceManager.GetString(\"menuImportRulesFromUrl\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to One-click multi test Latency and speed (Ctrl+E).\n        /// </summary>\n        public static string menuMixedTestServer {\n            get {\n                return ResourceManager.GetString(\"menuMixedTestServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Move to bottom (B).\n        /// </summary>\n        public static string menuMoveBottom {\n            get {\n                return ResourceManager.GetString(\"menuMoveBottom\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Down (D).\n        /// </summary>\n        public static string menuMoveDown {\n            get {\n                return ResourceManager.GetString(\"menuMoveDown\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Move up and down.\n        /// </summary>\n        public static string menuMoveTo {\n            get {\n                return ResourceManager.GetString(\"menuMoveTo\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Move to group.\n        /// </summary>\n        public static string menuMoveToGroup {\n            get {\n                return ResourceManager.GetString(\"menuMoveToGroup\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Move to top (T).\n        /// </summary>\n        public static string menuMoveTop {\n            get {\n                return ResourceManager.GetString(\"menuMoveTop\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Up (U).\n        /// </summary>\n        public static string menuMoveUp {\n            get {\n                return ResourceManager.GetString(\"menuMoveUp\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear All.\n        /// </summary>\n        public static string menuMsgViewClear {\n            get {\n                return ResourceManager.GetString(\"menuMsgViewClear\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy (Ctrl+C).\n        /// </summary>\n        public static string menuMsgViewCopy {\n            get {\n                return ResourceManager.GetString(\"menuMsgViewCopy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy All.\n        /// </summary>\n        public static string menuMsgViewCopyAll {\n            get {\n                return ResourceManager.GetString(\"menuMsgViewCopyAll\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set message filters.\n        /// </summary>\n        public static string menuMsgViewFilter {\n            get {\n                return ResourceManager.GetString(\"menuMsgViewFilter\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select All (Ctrl+A).\n        /// </summary>\n        public static string menuMsgViewSelectAll {\n            get {\n                return ResourceManager.GetString(\"menuMsgViewSelectAll\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to OptionSetting.\n        /// </summary>\n        public static string menuOptionSetting {\n            get {\n                return ResourceManager.GetString(\"menuOptionSetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test servers ping (Ctrl+P).\n        /// </summary>\n        public static string menuPingServer {\n            get {\n                return ResourceManager.GetString(\"menuPingServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Channel.\n        /// </summary>\n        public static string menuPromotion {\n            get {\n                return ResourceManager.GetString(\"menuPromotion\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test servers real delay (Ctrl+R).\n        /// </summary>\n        public static string menuRealPingServer {\n            get {\n                return ResourceManager.GetString(\"menuRealPingServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Reboot as administrator 的本地化字符串。\n        /// </summary>\n        public static string menuRebootAsAdmin {\n            get {\n                return ResourceManager.GetString(\"menuRebootAsAdmin\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Reload 的本地化字符串。\n        /// </summary>\n        public static string menuReload {\n            get {\n                return ResourceManager.GetString(\"menuReload\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove duplicate servers.\n        /// </summary>\n        public static string menuRemoveDuplicateServer {\n            get {\n                return ResourceManager.GetString(\"menuRemoveDuplicateServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove selected servers (Delete).\n        /// </summary>\n        public static string menuRemoveServer {\n            get {\n                return ResourceManager.GetString(\"menuRemoveServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Routing.\n        /// </summary>\n        public static string menuRouting {\n            get {\n                return ResourceManager.GetString(\"menuRouting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Advanced Function.\n        /// </summary>\n        public static string menuRoutingAdvanced {\n            get {\n                return ResourceManager.GetString(\"menuRoutingAdvanced\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add.\n        /// </summary>\n        public static string menuRoutingAdvancedAdd {\n            get {\n                return ResourceManager.GetString(\"menuRoutingAdvancedAdd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Import Advanced Rules.\n        /// </summary>\n        public static string menuRoutingAdvancedImportRules {\n            get {\n                return ResourceManager.GetString(\"menuRoutingAdvancedImportRules\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Remove selected (Delete) 的本地化字符串。\n        /// </summary>\n        public static string menuRoutingAdvancedRemove {\n            get {\n                return ResourceManager.GetString(\"menuRoutingAdvancedRemove\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set as active rule.\n        /// </summary>\n        public static string menuRoutingAdvancedSetDefault {\n            get {\n                return ResourceManager.GetString(\"menuRoutingAdvancedSetDefault\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Basic Function.\n        /// </summary>\n        public static string menuRoutingBasic {\n            get {\n                return ResourceManager.GetString(\"menuRoutingBasic\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Import Basic Rules.\n        /// </summary>\n        public static string menuRoutingBasicImportRules {\n            get {\n                return ResourceManager.GetString(\"menuRoutingBasicImportRules\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to RoutingRuleDetailsSetting.\n        /// </summary>\n        public static string menuRoutingRuleDetailsSetting {\n            get {\n                return ResourceManager.GetString(\"menuRoutingRuleDetailsSetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Rule Setting.\n        /// </summary>\n        public static string menuRoutingRuleSetting {\n            get {\n                return ResourceManager.GetString(\"menuRoutingRuleSetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to RoutingSetting.\n        /// </summary>\n        public static string menuRoutingSetting {\n            get {\n                return ResourceManager.GetString(\"menuRoutingSetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Rule Add.\n        /// </summary>\n        public static string menuRuleAdd {\n            get {\n                return ResourceManager.GetString(\"menuRuleAdd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Export Selected Rules.\n        /// </summary>\n        public static string menuRuleExportSelected {\n            get {\n                return ResourceManager.GetString(\"menuRuleExportSelected\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Rule List.\n        /// </summary>\n        public static string menuRuleList {\n            get {\n                return ResourceManager.GetString(\"menuRuleList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Remove Rules.\n        /// </summary>\n        public static string menuRuleRemove {\n            get {\n                return ResourceManager.GetString(\"menuRuleRemove\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Select All (Ctrl+A).\n        /// </summary>\n        public static string menuSelectAll {\n            get {\n                return ResourceManager.GetString(\"menuSelectAll\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Servers.\n        /// </summary>\n        public static string menuServers {\n            get {\n                return ResourceManager.GetString(\"menuServers\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set as active server (Enter).\n        /// </summary>\n        public static string menuSetDefaultServer {\n            get {\n                return ResourceManager.GetString(\"menuSetDefaultServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Setting.\n        /// </summary>\n        public static string menuSetting {\n            get {\n                return ResourceManager.GetString(\"menuSetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Share Server (Ctrl+F).\n        /// </summary>\n        public static string menuShareServer {\n            get {\n                return ResourceManager.GetString(\"menuShareServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Sort by test result.\n        /// </summary>\n        public static string menuSortServerResult {\n            get {\n                return ResourceManager.GetString(\"menuSortServerResult\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test servers download speed (Ctrl+T).\n        /// </summary>\n        public static string menuSpeedServer {\n            get {\n                return ResourceManager.GetString(\"menuSpeedServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Add.\n        /// </summary>\n        public static string menuSubAdd {\n            get {\n                return ResourceManager.GetString(\"menuSubAdd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Delete.\n        /// </summary>\n        public static string menuSubDelete {\n            get {\n                return ResourceManager.GetString(\"menuSubDelete\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Edit.\n        /// </summary>\n        public static string menuSubEdit {\n            get {\n                return ResourceManager.GetString(\"menuSubEdit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update current subscription without proxy.\n        /// </summary>\n        public static string menuSubGroupUpdate {\n            get {\n                return ResourceManager.GetString(\"menuSubGroupUpdate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update current subscription with proxy.\n        /// </summary>\n        public static string menuSubGroupUpdateViaProxy {\n            get {\n                return ResourceManager.GetString(\"menuSubGroupUpdateViaProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Subs group.\n        /// </summary>\n        public static string menuSubscription {\n            get {\n                return ResourceManager.GetString(\"menuSubscription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Subscription group Settings 的本地化字符串。\n        /// </summary>\n        public static string menuSubSetting {\n            get {\n                return ResourceManager.GetString(\"menuSubSetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Share.\n        /// </summary>\n        public static string menuSubShare {\n            get {\n                return ResourceManager.GetString(\"menuSubShare\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update subscription without proxy.\n        /// </summary>\n        public static string menuSubUpdate {\n            get {\n                return ResourceManager.GetString(\"menuSubUpdate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update subscription with proxy.\n        /// </summary>\n        public static string menuSubUpdateViaProxy {\n            get {\n                return ResourceManager.GetString(\"menuSubUpdateViaProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to System proxy.\n        /// </summary>\n        public static string menuSystemproxy {\n            get {\n                return ResourceManager.GetString(\"menuSystemproxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear system proxy.\n        /// </summary>\n        public static string menuSystemProxyClear {\n            get {\n                return ResourceManager.GetString(\"menuSystemProxyClear\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Do not change system proxy.\n        /// </summary>\n        public static string menuSystemProxyNothing {\n            get {\n                return ResourceManager.GetString(\"menuSystemProxyNothing\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Pac Mode.\n        /// </summary>\n        public static string menuSystemProxyPac {\n            get {\n                return ResourceManager.GetString(\"menuSystemProxyPac\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set system proxy.\n        /// </summary>\n        public static string menuSystemProxySet {\n            get {\n                return ResourceManager.GetString(\"menuSystemProxySet\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test servers with tcping (Ctrl+O).\n        /// </summary>\n        public static string menuTcpingServer {\n            get {\n                return ResourceManager.GetString(\"menuTcpingServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test current service status.\n        /// </summary>\n        public static string menuTestMe {\n            get {\n                return ResourceManager.GetString(\"menuTestMe\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} Website.\n        /// </summary>\n        public static string menuWebsiteItem {\n            get {\n                return ResourceManager.GetString(\"menuWebsiteItem\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear original subscription content.\n        /// </summary>\n        public static string MsgClearSubscription {\n            get {\n                return ResourceManager.GetString(\"MsgClearSubscription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The link is invalid.\n        /// </summary>\n        public static string MsgDeepLinkIsInvalid {\n            get {\n                return ResourceManager.GetString(\"MsgDeepLinkIsInvalid\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Download GeoFile: {0} successfully.\n        /// </summary>\n        public static string MsgDownloadGeoFileSuccessfully {\n            get {\n                return ResourceManager.GetString(\"MsgDownloadGeoFileSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Download Core successfully.\n        /// </summary>\n        public static string MsgDownloadV2rayCoreSuccessfully {\n            get {\n                return ResourceManager.GetString(\"MsgDownloadV2rayCoreSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Failed to import subscription content.\n        /// </summary>\n        public static string MsgFailedImportSubscription {\n            get {\n                return ResourceManager.GetString(\"MsgFailedImportSubscription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Filter, support regular.\n        /// </summary>\n        public static string MsgFilterTitle {\n            get {\n                return ResourceManager.GetString(\"MsgFilterTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Get subscription content successfully.\n        /// </summary>\n        public static string MsgGetSubscriptionSuccessfully {\n            get {\n                return ResourceManager.GetString(\"MsgGetSubscriptionSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Information.\n        /// </summary>\n        public static string MsgInformationTitle {\n            get {\n                return ResourceManager.GetString(\"MsgInformationTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please fill in the Url.\n        /// </summary>\n        public static string MsgNeedUrl {\n            get {\n                return ResourceManager.GetString(\"MsgNeedUrl\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Nothing has been Updated.\n        /// </summary>\n        public static string MsgNothingUpdated {\n            get {\n                return ResourceManager.GetString(\"MsgNothingUpdated\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to No valid subscriptions set.\n        /// </summary>\n        public static string MsgNoValidSubscription {\n            get {\n                return ResourceManager.GetString(\"MsgNoValidSubscription\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to PAC update failed.\n        /// </summary>\n        public static string MsgPACUpdateFailed {\n            get {\n                return ResourceManager.GetString(\"MsgPACUpdateFailed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to PAC update succeeded.\n        /// </summary>\n        public static string MsgPACUpdateSuccessfully {\n            get {\n                return ResourceManager.GetString(\"MsgPACUpdateSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Resolve {0} successfully.\n        /// </summary>\n        public static string MsgParsingSuccessfully {\n            get {\n                return ResourceManager.GetString(\"MsgParsingSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Servers Filter, press Enter to execute 的本地化字符串。\n        /// </summary>\n        public static string MsgProgramNeedsRestarting {\n            get {\n                return ResourceManager.GetString(\"MsgProgramNeedsRestarting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Servers Filter.\n        /// </summary>\n        public static string MsgServerTitle {\n            get {\n                return ResourceManager.GetString(\"MsgServerTitle\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Updates are not enabled, skip this subscription 的本地化字符串。\n        /// </summary>\n        public static string MsgSkipSubscriptionUpdate {\n            get {\n                return ResourceManager.GetString(\"MsgSkipSubscriptionUpdate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Start getting subscriptions.\n        /// </summary>\n        public static string MsgStartGettingSubscriptions {\n            get {\n                return ResourceManager.GetString(\"MsgStartGettingSubscriptions\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to To do this, the program must be run in Administrator mode.\n        /// </summary>\n        public static string MsgStartProgramAsAdmin {\n            get {\n                return ResourceManager.GetString(\"MsgStartProgramAsAdmin\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Start updating {0}....\n        /// </summary>\n        public static string MsgStartUpdating {\n            get {\n                return ResourceManager.GetString(\"MsgStartUpdating\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Start updating PAC....\n        /// </summary>\n        public static string MsgStartUpdatingPAC {\n            get {\n                return ResourceManager.GetString(\"MsgStartUpdatingPAC\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Invalid subscription content.\n        /// </summary>\n        public static string MsgSubscriptionDecodingFailed {\n            get {\n                return ResourceManager.GetString(\"MsgSubscriptionDecodingFailed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to is unpacking....\n        /// </summary>\n        public static string MsgUnpacking {\n            get {\n                return ResourceManager.GetString(\"MsgUnpacking\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update subscription end.\n        /// </summary>\n        public static string MsgUpdateSubscriptionEnd {\n            get {\n                return ResourceManager.GetString(\"MsgUpdateSubscriptionEnd\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update subscription starts.\n        /// </summary>\n        public static string MsgUpdateSubscriptionStart {\n            get {\n                return ResourceManager.GetString(\"MsgUpdateSubscriptionStart\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update Core successfully.\n        /// </summary>\n        public static string MsgUpdateV2rayCoreSuccessfully {\n            get {\n                return ResourceManager.GetString(\"MsgUpdateV2rayCoreSuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Update Core successfully! Restarting service....\n        /// </summary>\n        public static string MsgUpdateV2rayCoreSuccessfullyMore {\n            get {\n                return ResourceManager.GetString(\"MsgUpdateV2rayCoreSuccessfullyMore\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to  This feature relies on the Http global proxy, please set it correctly first..\n        /// </summary>\n        public static string NeedHttpGlobalProxy {\n            get {\n                return ResourceManager.GetString(\"NeedHttpGlobalProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Normal use of this version requires .NET Framework 4.8.\n        /// </summary>\n        public static string NetFrameworkRequirementsTip {\n            get {\n                return ResourceManager.GetString(\"NetFrameworkRequirementsTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Non-VMess or ss protocol.\n        /// </summary>\n        public static string NonvmessOrssProtocol {\n            get {\n                return ResourceManager.GetString(\"NonvmessOrssProtocol\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to  non-standard service, this feature is invalid.\n        /// </summary>\n        public static string NonVmessService {\n            get {\n                return ResourceManager.GetString(\"NonVmessService\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The Core file (file name: {1}) was not found under the folder ({0}), please download and put it in the folder, download address: {2}.\n        /// </summary>\n        public static string NotFoundCore {\n            get {\n                return ResourceManager.GetString(\"NotFoundCore\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Not Run As Admin.\n        /// </summary>\n        public static string NotRunAsAdmin {\n            get {\n                return ResourceManager.GetString(\"NotRunAsAdmin\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Scan completed, no valid QR code found.\n        /// </summary>\n        public static string NoValidQRcodeFound {\n            get {\n                return ResourceManager.GetString(\"NoValidQRcodeFound\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to  operation failed, please check and retry.\n        /// </summary>\n        public static string OperationFailed {\n            get {\n                return ResourceManager.GetString(\"OperationFailed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Operation success.\n        /// </summary>\n        public static string OperationSuccess {\n            get {\n                return ResourceManager.GetString(\"OperationSuccess\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please Fill Remarks.\n        /// </summary>\n        public static string PleaseFillRemarks {\n            get {\n                return ResourceManager.GetString(\"PleaseFillRemarks\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please select the encryption method.\n        /// </summary>\n        public static string PleaseSelectEncryption {\n            get {\n                return ResourceManager.GetString(\"PleaseSelectEncryption\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please select a protocol.\n        /// </summary>\n        public static string PleaseSelectProtocol {\n            get {\n                return ResourceManager.GetString(\"PleaseSelectProtocol\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please select rules.\n        /// </summary>\n        public static string PleaseSelectRules {\n            get {\n                return ResourceManager.GetString(\"PleaseSelectRules\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please select the server first.\n        /// </summary>\n        public static string PleaseSelectServer {\n            get {\n                return ResourceManager.GetString(\"PleaseSelectServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Fast.\n        /// </summary>\n        public static string QuickFresh {\n            get {\n                return ResourceManager.GetString(\"QuickFresh\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Global hotkey {0} registered failed, reason {1}.\n        /// </summary>\n        public static string RegisterGlobalHotkeyFailed {\n            get {\n                return ResourceManager.GetString(\"RegisterGlobalHotkeyFailed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Global hotkey {0} registered successfully.\n        /// </summary>\n        public static string RegisterGlobalHotkeySuccessfully {\n            get {\n                return ResourceManager.GetString(\"RegisterGlobalHotkeySuccessfully\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Servers deduplication completed. Old: {0}, New: {1}..\n        /// </summary>\n        public static string RemoveDuplicateServerResult {\n            get {\n                return ResourceManager.GetString(\"RemoveDuplicateServerResult\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Are you sure to remove the rules?.\n        /// </summary>\n        public static string RemoveRules {\n            get {\n                return ResourceManager.GetString(\"RemoveRules\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Are you sure to remove the server?.\n        /// </summary>\n        public static string RemoveServer {\n            get {\n                return ResourceManager.GetString(\"RemoveServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to All Sites.\n        /// </summary>\n        public static string RoutingAllSites {\n            get {\n                return ResourceManager.GetString(\"RoutingAllSites\", resourceCulture);\n            }\n        }\n\n        public static string HomeAdvancedSettings\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeAdvancedSettings\", resourceCulture);\n            }\n        }\n        public static string HomeImport\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeImport\", resourceCulture);\n            }\n        }\n        public static string HomeDelay\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeDelay\", resourceCulture);\n            }\n        }\n        public static string HomeRemaining\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeRemaining\", resourceCulture);\n            }\n        }\n        public static string HomeConnected\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeConnected\", resourceCulture);\n            }\n        }\n        public static string HomeNotConnected\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeNotConnected\", resourceCulture);\n            }\n        }\n        public static string HomeDisconnected\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeDisconnected\", resourceCulture);\n            }\n        }\n        public static string HomeProxyAuto\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeProxyAuto\", resourceCulture);\n            }\n        }\n        public static string HomeProxyLoadBalance\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeProxyLoadBalance\", resourceCulture);\n            }\n        }\n        public static string HomeProxyManual\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeProxyManual\", resourceCulture);\n            }\n        }\n        public static string HomeProxyModeSelection\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeProxyModeSelection\", resourceCulture);\n            }\n        }\n        public static string HomeConnecting\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeConnecting\", resourceCulture);\n            }\n        }\n        public static string HomeDays\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeDays\", resourceCulture);\n            }\n        }\n        public static string HomeUsage\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeUsage\", resourceCulture);\n            }\n        }\n\n        public static string HomeDelete\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeDelete\", resourceCulture);\n            }\n        }\n        public static string HomeWelcomeMsg\n        {\n            get\n            {\n                return ResourceManager.GetString(\"HomeWelcomeMsg\", resourceCulture);\n            }\n        }\n        /// <summary>\n        ///   Looks up a localized string similar to Blocked Sites.\n        /// </summary>\n        public static string RoutingBlockedSites {\n            get {\n                return ResourceManager.GetString(\"RoutingBlockedSites\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Foreign Sites.\n        /// </summary>\n        public static string RoutingForeignSites {\n            get {\n                return ResourceManager.GetString(\"RoutingForeignSites\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0},One of the required..\n        /// </summary>\n        public static string RoutingRuleDetailRequiredTips {\n            get {\n                return ResourceManager.GetString(\"RoutingRuleDetailRequiredTips\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Run As Admin.\n        /// </summary>\n        public static string RunAsAdmin {\n            get {\n                return ResourceManager.GetString(\"RunAsAdmin\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The client configuration file is saved at: {0}.\n        /// </summary>\n        public static string SaveClientConfigurationIn {\n            get {\n                return ResourceManager.GetString(\"SaveClientConfigurationIn\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 {0}:{1}/s↑ | {2}/s↓ 的本地化字符串。\n        /// </summary>\n        public static string SpeedDisplayText {\n            get {\n                return ResourceManager.GetString(\"SpeedDisplayText\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Slow.\n        /// </summary>\n        public static string SlowFresh {\n            get {\n                return ResourceManager.GetString(\"SlowFresh\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Note: This feature relies on the Http global proxy. Please manually adjust the Http global proxy and active node after testing..\n        /// </summary>\n        public static string SpeedServerTips {\n            get {\n                return ResourceManager.GetString(\"SpeedServerTips\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Testing....\n        /// </summary>\n        public static string Speedtesting {\n            get {\n                return ResourceManager.GetString(\"Speedtesting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Test completed.\n        /// </summary>\n        public static string SpeedtestingCompleted {\n            get {\n                return ResourceManager.GetString(\"SpeedtestingCompleted\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Skip test.\n        /// </summary>\n        public static string SpeedtestingSkip {\n            get {\n                return ResourceManager.GetString(\"SpeedtestingSkip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Waiting for testing.\n        /// </summary>\n        public static string SpeedtestingWait {\n            get {\n                return ResourceManager.GetString(\"SpeedtestingWait\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to PAC failed to start. Please run this program as Administrator..\n        /// </summary>\n        public static string StartPacFailed {\n            get {\n                return ResourceManager.GetString(\"StartPacFailed\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Start service ({0})....\n        /// </summary>\n        public static string StartService {\n            get {\n                return ResourceManager.GetString(\"StartService\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Group please leave blank here.\n        /// </summary>\n        public static string SubUrlTips {\n            get {\n                return ResourceManager.GetString(\"SubUrlTips\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Configuration successful\n        ///{0}.\n        /// </summary>\n        public static string SuccessfulConfiguration {\n            get {\n                return ResourceManager.GetString(\"SuccessfulConfiguration\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Custom configuration server imported successfully..\n        /// </summary>\n        public static string SuccessfullyImportedCustomServer {\n            get {\n                return ResourceManager.GetString(\"SuccessfullyImportedCustomServer\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to {0} servers have been imported from clipboard..\n        /// </summary>\n        public static string SuccessfullyImportedServerViaClipboard {\n            get {\n                return ResourceManager.GetString(\"SuccessfullyImportedServerViaClipboard\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Scan import URL successfully.\n        /// </summary>\n        public static string SuccessfullyImportedServerViaScan {\n            get {\n                return ResourceManager.GetString(\"SuccessfullyImportedServerViaScan\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to System proxy.\n        /// </summary>\n        public static string SystemProxy {\n            get {\n                return ResourceManager.GetString(\"SystemProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Address.\n        /// </summary>\n        public static string TbAddress {\n            get {\n                return ResourceManager.GetString(\"TbAddress\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to AllowInsecure.\n        /// </summary>\n        public static string TbAllowInsecure {\n            get {\n                return ResourceManager.GetString(\"TbAllowInsecure\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Alpn.\n        /// </summary>\n        public static string TbAlpn {\n            get {\n                return ResourceManager.GetString(\"TbAlpn\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to AlterId.\n        /// </summary>\n        public static string TbAlterId {\n            get {\n                return ResourceManager.GetString(\"TbAlterId\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to AutoRefresh.\n        /// </summary>\n        public static string TbAutoRefresh {\n            get {\n                return ResourceManager.GetString(\"TbAutoRefresh\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Domain and ip are auto sorted when saving.\n        /// </summary>\n        public static string TbAutoSort {\n            get {\n                return ResourceManager.GetString(\"TbAutoSort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Browse.\n        /// </summary>\n        public static string TbBrowse {\n            get {\n                return ResourceManager.GetString(\"TbBrowse\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Cancel.\n        /// </summary>\n        public static string TbCancel {\n            get {\n                return ResourceManager.GetString(\"TbCancel\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Clear system proxy.\n        /// </summary>\n        public static string TbClearSystemProxy {\n            get {\n                return ResourceManager.GetString(\"TbClearSystemProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Confirm.\n        /// </summary>\n        public static string TbConfirm {\n            get {\n                return ResourceManager.GetString(\"TbConfirm\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Core Type.\n        /// </summary>\n        public static string TbCoreType {\n            get {\n                return ResourceManager.GetString(\"TbCoreType\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Display GUI.\n        /// </summary>\n        public static string TbDisplayGUI {\n            get {\n                return ResourceManager.GetString(\"TbDisplayGUI\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Display Log.\n        /// </summary>\n        public static string TbDisplayLog {\n            get {\n                return ResourceManager.GetString(\"TbDisplayLog\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Support DnsObject, Click to view the document 的本地化字符串。\n        /// </summary>\n        public static string TbDnsObjectDoc {\n            get {\n                return ResourceManager.GetString(\"TbDnsObjectDoc\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Please fill in DNS Structure, Click to view the document 的本地化字符串。\n        /// </summary>\n        public static string TbDnsSingboxObjectDoc {\n            get {\n                return ResourceManager.GetString(\"TbDnsSingboxObjectDoc\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Domain Matcher 的本地化字符串。\n        /// </summary>\n        public static string TbdomainMatcher {\n            get {\n                return ResourceManager.GetString(\"TbdomainMatcher\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Domain strategy.\n        /// </summary>\n        public static string TbdomainStrategy {\n            get {\n                return ResourceManager.GetString(\"TbdomainStrategy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Sing-box domain strategy 的本地化字符串。\n        /// </summary>\n        public static string TbdomainStrategy4Singbox {\n            get {\n                return ResourceManager.GetString(\"TbdomainStrategy4Singbox\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Edit 的本地化字符串。\n        /// </summary>\n        public static string TbEdit {\n            get {\n                return ResourceManager.GetString(\"TbEdit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Use Proxy.\n        /// </summary>\n        public static string TbEnableProxy {\n            get {\n                return ResourceManager.GetString(\"TbEnableProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable advanced function.\n        /// </summary>\n        public static string TbenableRoutingAdvanced {\n            get {\n                return ResourceManager.GetString(\"TbenableRoutingAdvanced\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable Tun.\n        /// </summary>\n        public static string TbEnableTunAs {\n            get {\n                return ResourceManager.GetString(\"TbEnableTunAs\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Fingerprint.\n        /// </summary>\n        public static string TbFingerprint {\n            get {\n                return ResourceManager.GetString(\"TbFingerprint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Flow.\n        /// </summary>\n        public static string TbFlow5 {\n            get {\n                return ResourceManager.GetString(\"TbFlow5\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 GlobalHotkey Settings 的本地化字符串。\n        /// </summary>\n        public static string TbGlobalHotkeySetting {\n            get {\n                return ResourceManager.GetString(\"TbGlobalHotkeySetting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set directly by pressing the keyboard, Take effect after restart.\n        /// </summary>\n        public static string TbGlobalHotkeySettingTip {\n            get {\n                return ResourceManager.GetString(\"TbGlobalHotkeySettingTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Generate.\n        /// </summary>\n        public static string TbGUID {\n            get {\n                return ResourceManager.GetString(\"TbGUID\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Camouflage type.\n        /// </summary>\n        public static string TbHeaderType {\n            get {\n                return ResourceManager.GetString(\"TbHeaderType\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to UUID(id).\n        /// </summary>\n        public static string TbId {\n            get {\n                return ResourceManager.GetString(\"TbId\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Password.\n        /// </summary>\n        public static string TbId3 {\n            get {\n                return ResourceManager.GetString(\"TbId3\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Password(Optional).\n        /// </summary>\n        public static string TbId4 {\n            get {\n                return ResourceManager.GetString(\"TbId4\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to UUID(id).\n        /// </summary>\n        public static string TbId5 {\n            get {\n                return ResourceManager.GetString(\"TbId5\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Transport protocol(network).\n        /// </summary>\n        public static string TbNetwork {\n            get {\n                return ResourceManager.GetString(\"TbNetwork\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Do not change system proxy.\n        /// </summary>\n        public static string TbNotChangeSystemProxy {\n            get {\n                return ResourceManager.GetString(\"TbNotChangeSystemProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Path.\n        /// </summary>\n        public static string TbPath {\n            get {\n                return ResourceManager.GetString(\"TbPath\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Port.\n        /// </summary>\n        public static string TbPort {\n            get {\n                return ResourceManager.GetString(\"TbPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to txtPreSocksPort.\n        /// </summary>\n        public static string TbPreSocksPort {\n            get {\n                return ResourceManager.GetString(\"TbPreSocksPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to PublicKey.\n        /// </summary>\n        public static string TbPublicKey {\n            get {\n                return ResourceManager.GetString(\"TbPublicKey\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Alias (remarks).\n        /// </summary>\n        public static string TbRemarks {\n            get {\n                return ResourceManager.GetString(\"TbRemarks\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Camouflage domain(host).\n        /// </summary>\n        public static string TbRequestHost {\n            get {\n                return ResourceManager.GetString(\"TbRequestHost\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Reset.\n        /// </summary>\n        public static string TbReset {\n            get {\n                return ResourceManager.GetString(\"TbReset\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to 3.Block Domain or IP.\n        /// </summary>\n        public static string TbRoutingTabBlock {\n            get {\n                return ResourceManager.GetString(\"TbRoutingTabBlock\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to 2.Direct Domain or IP.\n        /// </summary>\n        public static string TbRoutingTabDirect {\n            get {\n                return ResourceManager.GetString(\"TbRoutingTabDirect\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to 1.Proxy Domain or IP.\n        /// </summary>\n        public static string TbRoutingTabProxy {\n            get {\n                return ResourceManager.GetString(\"TbRoutingTabProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Pre-defined Rule Set List.\n        /// </summary>\n        public static string TbRoutingTabRuleList {\n            get {\n                return ResourceManager.GetString(\"TbRoutingTabRuleList\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *Set the rules, separated by commas (,); The comma in the regular is replaced by &lt;COMMA&gt;.\n        /// </summary>\n        public static string TbRoutingTips {\n            get {\n                return ResourceManager.GetString(\"TbRoutingTips\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Ruleobject Doc.\n        /// </summary>\n        public static string TbRuleobjectDoc {\n            get {\n                return ResourceManager.GetString(\"TbRuleobjectDoc\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Encryption method (security).\n        /// </summary>\n        public static string TbSecurity {\n            get {\n                return ResourceManager.GetString(\"TbSecurity\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Encryption.\n        /// </summary>\n        public static string TbSecurity3 {\n            get {\n                return ResourceManager.GetString(\"TbSecurity3\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to User(Optional).\n        /// </summary>\n        public static string TbSecurity4 {\n            get {\n                return ResourceManager.GetString(\"TbSecurity4\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Encryption.\n        /// </summary>\n        public static string TbSecurity5 {\n            get {\n                return ResourceManager.GetString(\"TbSecurity5\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set system proxy.\n        /// </summary>\n        public static string TbSetSystemProxy {\n            get {\n                return ResourceManager.GetString(\"TbSetSystemProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Click to import default DNS config 的本地化字符串。\n        /// </summary>\n        public static string TBSettingDnsImportDefConfig {\n            get {\n                return ResourceManager.GetString(\"TBSettingDnsImportDefConfig\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Advanced proxy settings, protocol selection (optional) 的本地化字符串。\n        /// </summary>\n        public static string TbSettingsAdvancedProtocol {\n            get {\n                return ResourceManager.GetString(\"TbSettingsAdvancedProtocol\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Allow connections from the LAN.\n        /// </summary>\n        public static string TbSettingsAllowLAN {\n            get {\n                return ResourceManager.GetString(\"TbSettingsAllowLAN\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Auto hide startup.\n        /// </summary>\n        public static string TbSettingsAutoHideStartup {\n            get {\n                return ResourceManager.GetString(\"TbSettingsAutoHideStartup\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Automatic update interval of Geo (hours) 的本地化字符串。\n        /// </summary>\n        public static string TbSettingsAutoTest {\n            get {\n                return ResourceManager.GetString(\"TbSettingsAutoTest\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Automatic update interval of subscriptions (hours).\n        /// </summary>\n        public static string TbSettingsAutoUpdate {\n            get {\n                return ResourceManager.GetString(\"TbSettingsAutoUpdate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Automatic update interval of and Geo (hours).\n        /// </summary>\n        public static string TbSettingsAutoUpdateInterval {\n            get {\n                return ResourceManager.GetString(\"TbSettingsAutoUpdateInterval\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Color.\n        /// </summary>\n        public static string TbSettingsColor {\n            get {\n                return ResourceManager.GetString(\"TbSettingsColor\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Dark Mode.\n        /// </summary>\n        public static string TbSettingsColorMode {\n            get {\n                return ResourceManager.GetString(\"TbSettingsColorMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Core: basic settings.\n        /// </summary>\n        public static string TbSettingsCore {\n            get {\n                return ResourceManager.GetString(\"TbSettingsCore\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 V2ray DNS settings 的本地化字符串。\n        /// </summary>\n        public static string TbSettingsCoreDns {\n            get {\n                return ResourceManager.GetString(\"TbSettingsCoreDns\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Sing-box DNS settings 的本地化字符串。\n        /// </summary>\n        public static string TbSettingsCoreDnsSingbox {\n            get {\n                return ResourceManager.GetString(\"TbSettingsCoreDnsSingbox\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Core: KCP settings 的本地化字符串。\n        /// </summary>\n        public static string TbSettingsCoreKcp {\n            get {\n                return ResourceManager.GetString(\"TbSettingsCoreKcp\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to CoreType settings.\n        /// </summary>\n        public static string TbSettingsCoreType {\n            get {\n                return ResourceManager.GetString(\"TbSettingsCoreType\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to FontFamily(Require restart).\n        /// </summary>\n        public static string TbSettingsCurrentFontFamily {\n            get {\n                return ResourceManager.GetString(\"TbSettingsCurrentFontFamily\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Copy the font TTF file to the directory guiFonts, restart the settings.\n        /// </summary>\n        public static string TbSettingsCurrentFontFamilyTip {\n            get {\n                return ResourceManager.GetString(\"TbSettingsCurrentFontFamilyTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to AllowInsecure.\n        /// </summary>\n        public static string TbSettingsDefAllowInsecure {\n            get {\n                return ResourceManager.GetString(\"TbSettingsDefAllowInsecure\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Default TLS fingerprint.\n        /// </summary>\n        public static string TbSettingsDefFingerprint {\n            get {\n                return ResourceManager.GetString(\"TbSettingsDefFingerprint\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to User-Agent.\n        /// </summary>\n        public static string TbSettingsDefUserAgent {\n            get {\n                return ResourceManager.GetString(\"TbSettingsDefUserAgent\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to This parameter is valid only for tcp/http and ws.\n        /// </summary>\n        public static string TbSettingsDefUserAgentTips {\n            get {\n                return ResourceManager.GetString(\"TbSettingsDefUserAgentTips\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Outbound Freedom domainStrategy.\n        /// </summary>\n        public static string TbSettingsDomainStrategy4Freedom {\n            get {\n                return ResourceManager.GetString(\"TbSettingsDomainStrategy4Freedom\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Double-click server make active.\n        /// </summary>\n        public static string TbSettingsDoubleClick2Activate {\n            get {\n                return ResourceManager.GetString(\"TbSettingsDoubleClick2Activate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Automatically adjust column width after updating subscription.\n        /// </summary>\n        public static string TbSettingsEnableAutoAdjustMainLvColWidth {\n            get {\n                return ResourceManager.GetString(\"TbSettingsEnableAutoAdjustMainLvColWidth\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Check for pre-release updates.\n        /// </summary>\n        public static string TbSettingsEnableCheckPreReleaseUpdate {\n            get {\n                return ResourceManager.GetString(\"TbSettingsEnableCheckPreReleaseUpdate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable Server Drag Drop Sort(Require restart).\n        /// </summary>\n        public static string TbSettingsEnableDragDropSort {\n            get {\n                return ResourceManager.GetString(\"TbSettingsEnableDragDropSort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable hardware acceleration(Require restart).\n        /// </summary>\n        public static string TbSettingsEnableHWA {\n            get {\n                return ResourceManager.GetString(\"TbSettingsEnableHWA\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Exception.\n        /// </summary>\n        public static string TbSettingsException {\n            get {\n                return ResourceManager.GetString(\"TbSettingsException\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Exception. Do not use proxy server for addresses beginning with,Use semicolon (;).\n        /// </summary>\n        public static string TbSettingsExceptionTip {\n            get {\n                return ResourceManager.GetString(\"TbSettingsExceptionTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to FontSize.\n        /// </summary>\n        public static string TbSettingsFontSize {\n            get {\n                return ResourceManager.GetString(\"TbSettingsFontSize\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Http Port.\n        /// </summary>\n        public static string TbSettingsHttpPort {\n            get {\n                return ResourceManager.GetString(\"TbSettingsHttpPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Ignore Geo files when updating core.\n        /// </summary>\n        public static string TbSettingsIgnoreGeoUpdateCore {\n            get {\n                return ResourceManager.GetString(\"TbSettingsIgnoreGeoUpdateCore\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable IPv6.\n        /// </summary>\n        public static string TbSettingsIpv6 {\n            get {\n                return ResourceManager.GetString(\"TbSettingsIpv6\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Keep older when deduplication.\n        /// </summary>\n        public static string TbSettingsKeepOlderDedupl {\n            get {\n                return ResourceManager.GetString(\"TbSettingsKeepOlderDedupl\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Language(Restart).\n        /// </summary>\n        public static string TbSettingsLanguage {\n            get {\n                return ResourceManager.GetString(\"TbSettingsLanguage\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable Log.\n        /// </summary>\n        public static string TbSettingsLogEnabled {\n            get {\n                return ResourceManager.GetString(\"TbSettingsLogEnabled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Enable logging to file 的本地化字符串。\n        /// </summary>\n        public static string TbSettingsLogEnabledToFile {\n            get {\n                return ResourceManager.GetString(\"TbSettingsLogEnabledToFile\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 Log Level 的本地化字符串。\n        /// </summary>\n        public static string TbSettingsLogLevel {\n            get {\n                return ResourceManager.GetString(\"TbSettingsLogLevel\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Turn on Mux Multiplexing.\n        /// </summary>\n        public static string TbSettingsMuxEnabled {\n            get {\n                return ResourceManager.GetString(\"TbSettingsMuxEnabled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to v2rayN settings.\n        /// </summary>\n        public static string TbSettingsN {\n            get {\n                return ResourceManager.GetString(\"TbSettingsN\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to New Port for LAN.\n        /// </summary>\n        public static string TbSettingsNewPort4LAN {\n            get {\n                return ResourceManager.GetString(\"TbSettingsNewPort4LAN\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Pac listen port.\n        /// </summary>\n        public static string TbSettingsPacListenPort {\n            get {\n                return ResourceManager.GetString(\"TbSettingsPacListenPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Auth pass.\n        /// </summary>\n        public static string TbSettingsPass {\n            get {\n                return ResourceManager.GetString(\"TbSettingsPass\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Custom DNS (multiple, separated by commas (,)).\n        /// </summary>\n        public static string TbSettingsRemoteDNS {\n            get {\n                return ResourceManager.GetString(\"TbSettingsRemoteDNS\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to RouteOnly.\n        /// </summary>\n        public static string TbSettingsRouteOnly {\n            get {\n                return ResourceManager.GetString(\"TbSettingsRouteOnly\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to After modifying the following parameters, click Save to take effect.\n        /// </summary>\n        public static string TbSettingsSaveTip {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSaveTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set Win10 UWP Loopback.\n        /// </summary>\n        public static string TbSettingsSetUWP {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSetUWP\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Turn on Sniffing.\n        /// </summary>\n        public static string TbSettingsSniffingEnabled {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSniffingEnabled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Socks Port.\n        /// </summary>\n        public static string TbSettingsSocksPort {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSocksPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to http port=socks port+1.\n        /// </summary>\n        public static string TbSettingsSocksPortTip {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSocksPortTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to SpeedTest Single Timeout Value.\n        /// </summary>\n        public static string TbSettingsSpeedTestTimeout {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSpeedTestTimeout\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to SpeedTest Url.\n        /// </summary>\n        public static string TbSettingsSpeedTestUrl {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSpeedTestUrl\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Start on boot.\n        /// </summary>\n        public static string TbSettingsStartBoot {\n            get {\n                return ResourceManager.GetString(\"TbSettingsStartBoot\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Set this with admin privileges, get admin privileges after startup.\n        /// </summary>\n        public static string TbSettingsStartBootTip {\n            get {\n                return ResourceManager.GetString(\"TbSettingsStartBootTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable Statistics (Require restart).\n        /// </summary>\n        public static string TbSettingsStatistics {\n            get {\n                return ResourceManager.GetString(\"TbSettingsStatistics\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Statistics freshrate (second).\n        /// </summary>\n        public static string TbSettingsStatisticsFreshRate {\n            get {\n                return ResourceManager.GetString(\"TbSettingsStatisticsFreshRate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Subscription conversion Url.\n        /// </summary>\n        public static string TbSettingsSubConvert {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSubConvert\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to System proxy settings.\n        /// </summary>\n        public static string TbSettingsSystemproxy {\n            get {\n                return ResourceManager.GetString(\"TbSettingsSystemproxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable Security Protocol TLS v1.3 (subscription/update).\n        /// </summary>\n        public static string TbSettingsTLS13 {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTLS13\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Tray right-click menu servers display limit.\n        /// </summary>\n        public static string TbSettingsTrayMenuServersLimit {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTrayMenuServersLimit\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to TunMode settings.\n        /// </summary>\n        public static string TbSettingsTunMode {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Bypass Mode.\n        /// </summary>\n        public static string TbSettingsTunModeBypassMode {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeBypassMode\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable: If no route matches, the final proxy.\n        /// </summary>\n        public static string TbSettingsTunModeBypassModeTip {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeBypassModeTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Custom Template.\n        /// </summary>\n        public static string TbSettingsTunModeCustomTemplate {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeCustomTemplate\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Direct IP CIDR, separated by commas (,).\n        /// </summary>\n        public static string TbSettingsTunModeDirectIP {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeDirectIP\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Direct Process name, separated by commas (,).\n        /// </summary>\n        public static string TbSettingsTunModeDirectProcess {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeDirectProcess\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to DNS object, e.g. {&quot;servers&quot;:[]}.\n        /// </summary>\n        public static string TbSettingsTunModeDNS {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeDNS\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Proxy IP CIDR, separated by commas (,).\n        /// </summary>\n        public static string TbSettingsTunModeProxyIP {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeProxyIP\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Proxy Process name, separated by commas (,).\n        /// </summary>\n        public static string TbSettingsTunModeProxyProcess {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeProxyProcess\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Show console.\n        /// </summary>\n        public static string TbSettingsTunModeShowWindow {\n            get {\n                return ResourceManager.GetString(\"TbSettingsTunModeShowWindow\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Enable UDP.\n        /// </summary>\n        public static string TbSettingsUdpEnabled {\n            get {\n                return ResourceManager.GetString(\"TbSettingsUdpEnabled\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Auth user.\n        /// </summary>\n        public static string TbSettingsUser {\n            get {\n                return ResourceManager.GetString(\"TbSettingsUser\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to ShortId.\n        /// </summary>\n        public static string TbShortId {\n            get {\n                return ResourceManager.GetString(\"TbShortId\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to SNI.\n        /// </summary>\n        public static string TbSNI {\n            get {\n                return ResourceManager.GetString(\"TbSNI\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to SpiderX.\n        /// </summary>\n        public static string TbSpiderX {\n            get {\n                return ResourceManager.GetString(\"TbSpiderX\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to TLS.\n        /// </summary>\n        public static string TbStreamSecurity {\n            get {\n                return ResourceManager.GetString(\"TbStreamSecurity\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Pac Mode.\n        /// </summary>\n        public static string TbSystemProxyPac {\n            get {\n                return ResourceManager.GetString(\"TbSystemProxyPac\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to The ping of current service: {0} ms.\n        /// </summary>\n        public static string TestMeOutput {\n            get {\n                return ResourceManager.GetString(\"TestMeOutput\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Routing setting is changed.\n        /// </summary>\n        public static string TipChangeRouting {\n            get {\n                return ResourceManager.GetString(\"TipChangeRouting\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to System proxy setting is changed.\n        /// </summary>\n        public static string TipChangeSystemProxy {\n            get {\n                return ResourceManager.GetString(\"TipChangeSystemProxy\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Please turn off when there is an abnormal disconnection.\n        /// </summary>\n        public static string TipDisplayLog {\n            get {\n                return ResourceManager.GetString(\"TipDisplayLog\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *Default value tcp.\n        /// </summary>\n        public static string TipNetwork {\n            get {\n                return ResourceManager.GetString(\"TipNetwork\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   查找类似 * After setting this value, an socks service will be started using Sing-box to provide functions such as speed display 的本地化字符串。\n        /// </summary>\n        public static string TipPreSocksPort {\n            get {\n                return ResourceManager.GetString(\"TipPreSocksPort\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Too many servers, please open the main interface.\n        /// </summary>\n        public static string TooManyServersTip {\n            get {\n                return ResourceManager.GetString(\"TooManyServersTip\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *tcp camouflage type.\n        /// </summary>\n        public static string TransportHeaderTypeTip1 {\n            get {\n                return ResourceManager.GetString(\"TransportHeaderTypeTip1\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *kcp camouflage type.\n        /// </summary>\n        public static string TransportHeaderTypeTip2 {\n            get {\n                return ResourceManager.GetString(\"TransportHeaderTypeTip2\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *QUIC camouflage type.\n        /// </summary>\n        public static string TransportHeaderTypeTip3 {\n            get {\n                return ResourceManager.GetString(\"TransportHeaderTypeTip3\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *grpc mode.\n        /// </summary>\n        public static string TransportHeaderTypeTip4 {\n            get {\n                return ResourceManager.GetString(\"TransportHeaderTypeTip4\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *ws path.\n        /// </summary>\n        public static string TransportPathTip1 {\n            get {\n                return ResourceManager.GetString(\"TransportPathTip1\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *h2 path.\n        /// </summary>\n        public static string TransportPathTip2 {\n            get {\n                return ResourceManager.GetString(\"TransportPathTip2\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *QUIC key/Kcp seed.\n        /// </summary>\n        public static string TransportPathTip3 {\n            get {\n                return ResourceManager.GetString(\"TransportPathTip3\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *grpc serviceName.\n        /// </summary>\n        public static string TransportPathTip4 {\n            get {\n                return ResourceManager.GetString(\"TransportPathTip4\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *Kcp seed.\n        /// </summary>\n        public static string TransportPathTip5 {\n            get {\n                return ResourceManager.GetString(\"TransportPathTip5\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *http host Separated by commas (,).\n        /// </summary>\n        public static string TransportRequestHostTip1 {\n            get {\n                return ResourceManager.GetString(\"TransportRequestHostTip1\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *ws host.\n        /// </summary>\n        public static string TransportRequestHostTip2 {\n            get {\n                return ResourceManager.GetString(\"TransportRequestHostTip2\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *h2 host Separated by commas (,).\n        /// </summary>\n        public static string TransportRequestHostTip3 {\n            get {\n                return ResourceManager.GetString(\"TransportRequestHostTip3\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to *QUIC security.\n        /// </summary>\n        public static string TransportRequestHostTip4 {\n            get {\n                return ResourceManager.GetString(\"TransportRequestHostTip4\", resourceCulture);\n            }\n        }\n        \n        /// <summary>\n        ///   Looks up a localized string similar to Ungrouped.\n        /// </summary>\n        public static string UngroupedServers {\n            get {\n                return ResourceManager.GetString(\"UngroupedServers\", resourceCulture);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Resx/ResUI.fa-Ir.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=\"BatchExportSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>صادرات دسته ای محتوای اشتراک به کلیپ بورد با موفقیت انجام شد</value>\n  </data>\n  <data name=\"BatchExportURLSuccessfully\" xml:space=\"preserve\">\n    <value>Batch export share URL to clipboard successfully</value>\n  </data>\n  <data name=\"CheckServerSettings\" xml:space=\"preserve\">\n    <value>لطفا ابتدا تنظیمات سرور را بررسی کنید</value>\n  </data>\n  <data name=\"ConfigurationFormatIncorrect\" xml:space=\"preserve\">\n    <value>فرمت پیکربندی نادرست است</value>\n  </data>\n  <data name=\"CustomServerTips\" xml:space=\"preserve\">\n    <value>توجه داشته باشید که پیکربندی سفارشی کاملاً به پیکربندی خود شما بستگی دارد و با همه تنظیمات کار نمی کند. اگر می خواهید از پروکسی سیستم استفاده کنید، لطفاً پورت درحال شنود را به صورت دستی تغییر دهید.</value>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>درحال دانلود...</value>\n  </data>\n  <data name=\"downloadSpeed\" xml:space=\"preserve\">\n    <value>دانلود</value>\n  </data>\n  <data name=\"DownloadYesNo\" xml:space=\"preserve\">\n    <value>Whether to download? {0}</value>\n  </data>\n  <data name=\"FailedConversionConfiguration\" xml:space=\"preserve\">\n    <value>تبدیل فایل پیکربندی انجام نشد</value>\n  </data>\n  <data name=\"FailedGenDefaultConfiguration\" xml:space=\"preserve\">\n    <value>فایل پیکربندی پیش فرض ایجاد نشد</value>\n  </data>\n  <data name=\"FailedGetDefaultConfiguration\" xml:space=\"preserve\">\n    <value>پیکربندی پیش فرض دریافت نشد</value>\n  </data>\n  <data name=\"FailedImportedCustomServer\" xml:space=\"preserve\">\n    <value>سرور پیکربندی سفارشی وارد نشد</value>\n  </data>\n  <data name=\"FailedReadConfiguration\" xml:space=\"preserve\">\n    <value>فایل پیکربندی خوانده نشد</value>\n  </data>\n  <data name=\"FillCorrectServerPort\" xml:space=\"preserve\">\n    <value>لطفا فرمت صحیح پورت سرور را پر کنید</value>\n  </data>\n  <data name=\"FillKcpParameters\" xml:space=\"preserve\">\n    <value>لطفاً پارامترهای KCP را به درستی پر کنید</value>\n  </data>\n  <data name=\"FillLocalListeningPort\" xml:space=\"preserve\">\n    <value>لطفاً پورت گوش دادن محلی را پر کنید</value>\n  </data>\n  <data name=\"FillPassword\" xml:space=\"preserve\">\n    <value>لطفا رمز عبور را وارد کنید</value>\n  </data>\n  <data name=\"FillServerAddress\" xml:space=\"preserve\">\n    <value>لطفا آدرس سرور را وارد کنید</value>\n  </data>\n  <data name=\"FillUUID\" xml:space=\"preserve\">\n    <value>لطفا شناسه کاربری را وارد کنید</value>\n  </data>\n  <data name=\"IncorrectClientConfiguration\" xml:space=\"preserve\">\n    <value>فایل پیکربندی مشتری صحیح نیست، لطفا بررسی کنید</value>\n  </data>\n  <data name=\"Incorrectconfiguration\" xml:space=\"preserve\">\n    <value>پیکربندی درستی نیست، لطفا بررسی کنید</value>\n  </data>\n  <data name=\"IncorrectServerConfiguration\" xml:space=\"preserve\">\n    <value>فایل پیکربندی سرور صحیح نیست، لطفا بررسی کنید</value>\n  </data>\n  <data name=\"InitialConfiguration\" xml:space=\"preserve\">\n    <value>پیکربندی اولیه</value>\n  </data>\n  <data name=\"IsLatestCore\" xml:space=\"preserve\">\n    <value>{0} در حال حاضر به روز است.</value>\n  </data>\n  <data name=\"IsLatestN\" xml:space=\"preserve\">\n    <value>{0} در حال حاضر به روز است.</value>\n  </data>\n  <data name=\"LvAddress\" xml:space=\"preserve\">\n    <value>آدرس</value>\n  </data>\n  <data name=\"LvEncryptionMethod\" xml:space=\"preserve\">\n    <value>امنیت</value>\n  </data>\n  <data name=\"LvPort\" xml:space=\"preserve\">\n    <value>پورت</value>\n  </data>\n  <data name=\"LvServiceType\" xml:space=\"preserve\">\n    <value>نوع</value>\n  </data>\n  <data name=\"LvSubscription\" xml:space=\"preserve\">\n    <value>گروه فرعی</value>\n  </data>\n  <data name=\"LvTodayDownloadDataAmount\" xml:space=\"preserve\">\n    <value> ترافیک دانلود امروز</value>\n  </data>\n  <data name=\"LvTodayUploadDataAmount\" xml:space=\"preserve\">\n    <value> ترافیک اپلود امروز</value>\n  </data>\n  <data name=\"LvTotalDownloadDataAmount\" xml:space=\"preserve\">\n    <value>کل ترافیک دانلود</value>\n  </data>\n  <data name=\"LvTotalUploadDataAmount\" xml:space=\"preserve\">\n    <value>کل ترافیک آپلود</value>\n  </data>\n  <data name=\"LvTransportProtocol\" xml:space=\"preserve\">\n    <value>جابجایی</value>\n  </data>\n  <data name=\"MsgClearSubscription\" xml:space=\"preserve\">\n    <value>محتوای اشتراک اصلی را پاک کنید</value>\n  </data>\n  <data name=\"MsgDownloadV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>دانلود Core با موفقیت</value>\n  </data>\n  <data name=\"MsgFailedImportSubscription\" xml:space=\"preserve\">\n    <value>محتوای اشتراک وارد نشد</value>\n  </data>\n  <data name=\"MsgGetSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>محتوای اشتراک با موفقیت دریافت شد</value>\n  </data>\n  <data name=\"MsgNoValidSubscription\" xml:space=\"preserve\">\n    <value>هیچ اشتراک معتبری تنظیم نشده است</value>\n  </data>\n  <data name=\"MsgParsingSuccessfully\" xml:space=\"preserve\">\n    <value>Resolve {0} successfully</value>\n  </data>\n  <data name=\"MsgStartGettingSubscriptions\" xml:space=\"preserve\">\n    <value>شروع به دریافت اشتراک شد</value>\n  </data>\n  <data name=\"MsgStartUpdating\" xml:space=\"preserve\">\n    <value>شروع بروزرسانی {0}...</value>\n  </data>\n  <data name=\"MsgSubscriptionDecodingFailed\" xml:space=\"preserve\">\n    <value>محتوای اشتراک نامعتبر است</value>\n  </data>\n  <data name=\"MsgUnpacking\" xml:space=\"preserve\">\n    <value>در حال باز کردن بسته می باشد ...</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionEnd\" xml:space=\"preserve\">\n    <value>بروزرسانی اشتراک به پایان رسید</value>\n  </data>\n  <data name=\"MsgNothingUpdated\" xml:space=\"preserve\">\n    <value>چیزی بروزرسانی نشد</value>\n  </data>\n  <data name=\"MsgStartProgramAsAdmin\" xml:space=\"preserve\">\n    <value>برای اجرای این عملیات، برنامه باید در حالت Administrator اجرا شود</value>\n  </data>\n  <data name=\"MsgDeepLinkIsInvalid\" xml:space=\"preserve\">\n    <value>لینک نامعتبر است</value>\n  </data>\n  <data name=\"MsgProgramNeedsRestarting\" xml:space=\"preserve\">\n    <value>! برای انجام این عملیات، برنامه باید راه‌اندازی مجدد شود</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionStart\" xml:space=\"preserve\">\n    <value>بروزرسانی اشتراک شروع شد</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>هسته با موفقیت بروزرسانی شد</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfullyMore\" xml:space=\"preserve\">\n    <value>هسته با موفقیت بروزرسانی شد! راه اندازی مجدد سرویس...</value>\n  </data>\n  <data name=\"NonvmessOrssProtocol\" xml:space=\"preserve\">\n    <value>Non-VMess or ss protocol</value>\n  </data>\n  <data name=\"NonVmessService\" xml:space=\"preserve\">\n    <value> non-standard service, this feature is invalid</value>\n  </data>\n  <data name=\"NotFoundCore\" xml:space=\"preserve\">\n    <value>The Core file (file name: {1}) was not found under the folder ({0}), please download and put it in the folder, download address: {2}</value>\n  </data>\n  <data name=\"NoValidQRcodeFound\" xml:space=\"preserve\">\n    <value>Scan completed, no valid QR code found</value>\n  </data>\n  <data name=\"OperationFailed\" xml:space=\"preserve\">\n    <value> عملیات انجام نشد، لطفا بررسی کنید و دوباره امتحان کنید</value>\n  </data>\n  <data name=\"PleaseFillRemarks\" xml:space=\"preserve\">\n    <value>Please Fill Remarks</value>\n  </data>\n  <data name=\"PleaseSelectEncryption\" xml:space=\"preserve\">\n    <value>لطفاً روش رمزگذاری را انتخاب کنید</value>\n  </data>\n  <data name=\"PleaseSelectProtocol\" xml:space=\"preserve\">\n    <value>لطفا یک پروتکل انتخاب کنید</value>\n  </data>\n  <data name=\"PleaseSelectServer\" xml:space=\"preserve\">\n    <value>لطفا ابتدا سرور را انتخاب کنید</value>\n  </data>\n  <data name=\"RemoveDuplicateServerResult\" xml:space=\"preserve\">\n    <value>Servers deduplication completed. Old: {0}, New: {1}.</value>\n  </data>\n  <data name=\"RemoveServer\" xml:space=\"preserve\">\n    <value>آیا مطمئن هستید که سرور را حذف می کنید؟</value>\n  </data>\n  <data name=\"SaveClientConfigurationIn\" xml:space=\"preserve\">\n    <value>The client configuration file is saved at: {0}</value>\n  </data>\n  <data name=\"StartService\" xml:space=\"preserve\">\n    <value>Start service ({0})...</value>\n  </data>\n  <data name=\"SuccessfulConfiguration\" xml:space=\"preserve\">\n    <value>پیکربندی با موفقیت انجام شد\n{0}</value>\n  </data>\n  <data name=\"SuccessfullyImportedCustomServer\" xml:space=\"preserve\">\n    <value>سرور پیکربندی سفارشی با موفقیت وارد شد.</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaClipboard\" xml:space=\"preserve\">\n    <value>{0} سرورها از کلیپ بورد وارد شده اند.</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaScan\" xml:space=\"preserve\">\n    <value>اسکن URL وارد کردن با موفقیت</value>\n  </data>\n  <data name=\"TestMeOutput\" xml:space=\"preserve\">\n    <value>پینگ سرویس فعلی: {0} ms</value>\n  </data>\n  <data name=\"OperationSuccess\" xml:space=\"preserve\">\n    <value>موفقیت عملیات</value>\n  </data>\n  <data name=\"PleaseSelectRules\" xml:space=\"preserve\">\n    <value>لطفا قوانین را انتخاب کنید</value>\n  </data>\n  <data name=\"RemoveRules\" xml:space=\"preserve\">\n    <value>آیا مطمئن هستید که قوانین را حذف می کنید؟</value>\n  </data>\n  <data name=\"RoutingRuleDetailRequiredTips\" xml:space=\"preserve\">\n    <value>{0},یکی از مورد نیاز.</value>\n  </data>\n  <data name=\"LvRemarks\" xml:space=\"preserve\">\n    <value>Remarks</value>\n  </data>\n  <data name=\"LvUrl\" xml:space=\"preserve\">\n    <value>Url(Optional)</value>\n  </data>\n  <data name=\"LvCount\" xml:space=\"preserve\">\n    <value>Count</value>\n  </data>\n  <data name=\"MsgNeedUrl\" xml:space=\"preserve\">\n    <value>Please fill in the address (Url)</value>\n  </data>\n  <data name=\"AddBatchRoutingRulesYesNo\" xml:space=\"preserve\">\n    <value>Do you want to append rules? Choose yes to append, choose otherwise to replace</value>\n  </data>\n  <data name=\"MsgDownloadGeoFileSuccessfully\" xml:space=\"preserve\">\n    <value>دانلود GeoFile: {0} با موفقیت</value>\n  </data>\n  <data name=\"HomeImport\" xml:space=\"preserve\">\n    <value>افزودن</value>\n  </data>\n  <data name=\"HomeDelete\" xml:space=\"preserve\">\n    <value>حذف</value>\n  </data>\n  <data name=\"HomeWelcomeMsg\" xml:space=\"preserve\">\n    <value>به هیدیفای خوش امدید</value>\n  </data>\n  <data name=\"HomeDays\" xml:space=\"preserve\">\n    <value>روز</value>\n  </data>\n  <data name=\"HomeUsage\" xml:space=\"preserve\">\n    <value>مصرف</value>\n  </data>\n  <data name=\"HomeConnected\" xml:space=\"preserve\">\n    <value>متصل شده</value>\n  </data>\n  <data name=\"HomeProxyAuto\" xml:space=\"preserve\">\n    <value>خودکار</value>\n  </data>\n  <data name=\"HomeProxyLoadBalance\" xml:space=\"preserve\">\n    <value>متعادل</value>\n  </data>\n  <data name=\"HomeProxyManual\" xml:space=\"preserve\">\n    <value>دستی</value>\n  </data>\n  <data name=\"HomeNotConnected\" xml:space=\"preserve\">\n    <value>متصل نشده</value>\n  </data>\n  <data name=\"HomeDisconnected\" xml:space=\"preserve\">\n    <value>قطع شده</value>\n  </data>\n  <data name=\"HomeRemaining\" xml:space=\"preserve\">\n    <value>باقیمانده</value>\n  </data>\n  <data name=\"HomeDelay\" xml:space=\"preserve\">\n    <value>تاخیر</value>\n  </data>\n  <data name=\"HomeConnecting\" xml:space=\"preserve\">\n    <value>در حال اتصال...</value>\n  </data>\n  <data name=\"HomeProxyModeSelection\" xml:space=\"preserve\">\n    <value>انتخاب حالت پروکسی</value>\n  </data>\n  <data name=\"MsgInformationTitle\" xml:space=\"preserve\">\n    <value>اطلاعات</value>\n  </data>\n  <data name=\"LvCustomIcon\" xml:space=\"preserve\">\n    <value>نماد سفارشی</value>\n  </data>\n  <data name=\"FillCorrectDNSText\" xml:space=\"preserve\">\n    <value>لطفاً DNS سفارشی صحیح را پر کنید</value>\n  </data>\n  <data name=\"HomeAdvancedSettings\" xml:space=\"preserve\">\n    <value>تنظیمات پیشرفته</value>\n  </data>\n  <data name=\"HomeDelay\" xml:space=\"preserve\">\n    <value>تاخیر</value>\n  </data>\n  <data name=\"TransportPathTip1\" xml:space=\"preserve\">\n    <value>ws path</value>\n  </data>\n  <data name=\"TransportPathTip2\" xml:space=\"preserve\">\n    <value>h2 path</value>\n  </data>\n  <data name=\"TransportPathTip3\" xml:space=\"preserve\">\n    <value>QUIC key/Kcp seed</value>\n  </data>\n  <data name=\"TransportPathTip4\" xml:space=\"preserve\">\n    <value>grpc serviceName</value>\n  </data>\n  <data name=\"TransportRequestHostTip1\" xml:space=\"preserve\">\n    <value>http host Separated by commas (,)</value>\n  </data>\n  <data name=\"TransportRequestHostTip2\" xml:space=\"preserve\">\n    <value>ws host</value>\n  </data>\n  <data name=\"TransportRequestHostTip3\" xml:space=\"preserve\">\n    <value>h2 host Separated by commas (,)</value>\n  </data>\n  <data name=\"TransportRequestHostTip4\" xml:space=\"preserve\">\n    <value>QUIC securty</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip1\" xml:space=\"preserve\">\n    <value>tcp camouflage type</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip2\" xml:space=\"preserve\">\n    <value>kcp camouflage type</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip3\" xml:space=\"preserve\">\n    <value>QUIC camouflage type</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip4\" xml:space=\"preserve\">\n    <value>grpc mode</value>\n  </data>\n  <data name=\"LvTLS\" xml:space=\"preserve\">\n    <value>TLS</value>\n  </data>\n  <data name=\"TransportPathTip5\" xml:space=\"preserve\">\n    <value>Kcp seed</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeyFailed\" xml:space=\"preserve\">\n    <value>Global hotkey {0} registered failed, reason {1}</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeySuccessfully\" xml:space=\"preserve\">\n    <value>Global hotkey {0} registered successfully</value>\n  </data>\n  <data name=\"UngroupedServers\" xml:space=\"preserve\">\n    <value>گروه بندی نشده</value>\n  </data>\n  <data name=\"AllGroupServers\" xml:space=\"preserve\">\n    <value>همه سرورها</value>\n  </data>\n  <data name=\"FillServerAddressCustom\" xml:space=\"preserve\">\n    <value>Please browse to import server configuration</value>\n  </data>\n  <data name=\"SystemProxy\" xml:space=\"preserve\">\n    <value>پروکسی سیستم</value>\n  </data>\n  <data name=\"Speedtesting\" xml:space=\"preserve\">\n    <value>درحال تست کردن...</value>\n  </data>\n  <data name=\"TooManyServersTip\" xml:space=\"preserve\">\n    <value>تعداد سرورها خیلی زیاد است، لطفا رابط اصلی را باز کنید</value>\n  </data>\n  <data name=\"LabLAN\" xml:space=\"preserve\">\n    <value>LAN</value>\n  </data>\n  <data name=\"LabLocal\" xml:space=\"preserve\">\n    <value>محلی</value>\n  </data>\n  <data name=\"MsgServerTitle\" xml:space=\"preserve\">\n    <value>فیلتر سرورها</value>\n  </data>\n  <data name=\"menuCheckUpdate\" xml:space=\"preserve\">\n    <value>بررسی بروزرسانی</value>\n  </data>\n  <data name=\"menuClose\" xml:space=\"preserve\">\n    <value>بستن</value>\n  </data>\n  <data name=\"menuExit\" xml:space=\"preserve\">\n    <value>خروج</value>\n  </data>\n  <data name=\"menuGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>تنظیم کلید میانبر کلی</value>\n  </data>\n  <data name=\"menuHelp\" xml:space=\"preserve\">\n    <value>کمک</value>\n  </data>\n  <data name=\"menuOptionSetting\" xml:space=\"preserve\">\n    <value>تنظیمات پارامتر</value>\n  </data>\n  <data name=\"menuPromotion\" xml:space=\"preserve\">\n    <value>اطلاع رسانی</value>\n  </data>\n  <data name=\"menuReload\" xml:space=\"preserve\">\n    <value>بارگذاری مجدد</value>\n  </data>\n  <data name=\"menuRoutingSetting\" xml:space=\"preserve\">\n    <value>تنظیم مسیریابی</value>\n  </data>\n  <data name=\"menuServers\" xml:space=\"preserve\">\n    <value>سرورها</value>\n  </data>\n  <data name=\"menuSetting\" xml:space=\"preserve\">\n    <value>تنظیمات</value>\n  </data>\n  <data name=\"menuSubGroupUpdate\" xml:space=\"preserve\">\n    <value>اشتراک فعلی را بدون پروکسی به روز شود</value>\n  </data>\n  <data name=\"menuSubGroupUpdateViaProxy\" xml:space=\"preserve\">\n    <value>اشتراک فعلی را با پروکسی به روز شود</value>\n  </data>\n  <data name=\"menuSubscription\" xml:space=\"preserve\">\n    <value>گروه اشتراک</value>\n  </data>\n  <data name=\"menuSubSetting\" xml:space=\"preserve\">\n    <value>تنظیم گروه اشتراک</value>\n  </data>\n  <data name=\"menuSubUpdate\" xml:space=\"preserve\">\n    <value>اشتراک را بدون پروکسی به روز شود</value>\n  </data>\n  <data name=\"menuSubUpdateViaProxy\" xml:space=\"preserve\">\n    <value>اشتراک را با پروکسی به روز شود</value>\n  </data>\n  <data name=\"menuSystemproxy\" xml:space=\"preserve\">\n    <value>پروکسی سیستم</value>\n  </data>\n  <data name=\"menuSystemProxyClear\" xml:space=\"preserve\">\n    <value>پاک کردن پروکسی سیستم</value>\n  </data>\n  <data name=\"menuSystemProxyNothing\" xml:space=\"preserve\">\n    <value>پروکسی سیستم تغییر نکند</value>\n  </data>\n  <data name=\"menuSystemProxyPac\" xml:space=\"preserve\">\n    <value>حالت Pac</value>\n  </data>\n  <data name=\"menuSystemProxySet\" xml:space=\"preserve\">\n    <value>تنظیم پراکسی سیستم</value>\n  </data>\n  <data name=\"TbSettingsColor\" xml:space=\"preserve\">\n    <value>رنگ</value>\n  </data>\n  <data name=\"TbSettingsColorMode\" xml:space=\"preserve\">\n    <value>حالت تاریک</value>\n  </data>\n  <data name=\"TbSettingsLanguage\" xml:space=\"preserve\">\n    <value>زبان</value>\n  </data>\n  <data name=\"menuAddServerViaClipboard\" xml:space=\"preserve\">\n    <value>وارد کردن URL انبوه از کلیپ بورد (Ctrl+V)</value>\n  </data>\n  <data name=\"menuAddServerViaScan\" xml:space=\"preserve\">\n    <value>اسکن کد QR روی صفحه (Ctrl+S)</value>\n  </data>\n  <data name=\"menuCopyServer\" xml:space=\"preserve\">\n    <value>سرور انتخاب شده را شبیه سازی کنید</value>\n  </data>\n  <data name=\"menuRemoveDuplicateServer\" xml:space=\"preserve\">\n    <value>سرورهای تکراری را حذف کنید</value>\n  </data>\n  <data name=\"menuRemoveServer\" xml:space=\"preserve\">\n    <value>حذف سرورهای انتخابی (Delete)</value>\n  </data>\n  <data name=\"menuSetDefaultServer\" xml:space=\"preserve\">\n    <value>به عنوان سرور فعال تنظیم کنید (Enter)</value>\n  </data>\n  <data name=\"menuClearServerStatistics\" xml:space=\"preserve\">\n    <value>تمام آمار خدمات را پاک کنید</value>\n  </data>\n  <data name=\"menuPingServer\" xml:space=\"preserve\">\n    <value>تست پینگ سرورها (Ctrl+P)</value>\n  </data>\n  <data name=\"menuRealPingServer\" xml:space=\"preserve\">\n    <value>آزمایش سرورها با تاخیر واقعی (Ctrl+R)</value>\n  </data>\n  <data name=\"menuSortServerResult\" xml:space=\"preserve\">\n    <value>مرتب سازی بر اساس نتیجه تست</value>\n  </data>\n  <data name=\"menuSpeedServer\" xml:space=\"preserve\">\n    <value>تست سرعت دانلود سرورها (Ctrl+T)</value>\n  </data>\n  <data name=\"menuTcpingServer\" xml:space=\"preserve\">\n    <value>تست سرورها با tcping (Ctrl+O)</value>\n  </data>\n  <data name=\"menuTestMe\" xml:space=\"preserve\">\n    <value>وضعیت سرویس فعلی را تست کنید</value>\n  </data>\n  <data name=\"menuExport2ClientConfig\" xml:space=\"preserve\">\n    <value>سرور انتخابی را برای پیکربندی کلاینت صادر کنید</value>\n  </data>\n  <data name=\"menuExport2ShareUrl\" xml:space=\"preserve\">\n    <value>URL های اشتراک گذاری را به کلیپ بورد صادر کنید (Ctrl+C)</value>\n  </data>\n  <data name=\"menuExport2SubContent\" xml:space=\"preserve\">\n    <value>اشتراک (base64) را به کلیپ بورد صادر کنید</value>\n  </data>\n  <data name=\"menuAddCustomServer\" xml:space=\"preserve\">\n    <value>یک سرور پیکربندی سفارشی اضافه شود</value>\n  </data>\n  <data name=\"menuAddShadowsocksServer\" xml:space=\"preserve\">\n    <value>سرور [شادوساکس] را اضافه کنید</value>\n  </data>\n  <data name=\"menuAddSocksServer\" xml:space=\"preserve\">\n    <value>سرور [ساکس] را اضافه کنید</value>\n  </data>\n  <data name=\"menuAddTrojanServer\" xml:space=\"preserve\">\n    <value>سرور [تروجان] را اضافه کنید</value>\n  </data>\n  <data name=\"menuAddVlessServer\" xml:space=\"preserve\">\n    <value>سرور [VLESS] را اضافه کنید</value>\n  </data>\n  <data name=\"menuAddVmessServer\" xml:space=\"preserve\">\n    <value>سرور [VMess] را اضافه کنید</value>\n  </data>\n  <data name=\"menuSelectAll\" xml:space=\"preserve\">\n    <value>انتخاب همه (Ctrl+A)</value>\n  </data>\n  <data name=\"menuMsgViewClear\" xml:space=\"preserve\">\n    <value>همه را پاک کن</value>\n  </data>\n  <data name=\"menuMsgViewCopy\" xml:space=\"preserve\">\n    <value>کپی (Ctrl+C)</value>\n  </data>\n  <data name=\"menuMsgViewCopyAll\" xml:space=\"preserve\">\n    <value>کپی همه</value>\n  </data>\n  <data name=\"menuMsgViewFilter\" xml:space=\"preserve\">\n    <value>فیلترهای پیام را تنظیم کنید</value>\n  </data>\n  <data name=\"menuMsgViewSelectAll\" xml:space=\"preserve\">\n    <value>انتخاب همه (Ctrl+A)</value>\n  </data>\n  <data name=\"menuSubAdd\" xml:space=\"preserve\">\n    <value>اضافه کردن</value>\n  </data>\n  <data name=\"menuSubDelete\" xml:space=\"preserve\">\n    <value>حذف</value>\n  </data>\n  <data name=\"menuSubEdit\" xml:space=\"preserve\">\n    <value>ویرایش</value>\n  </data>\n  <data name=\"menuSubShare\" xml:space=\"preserve\">\n    <value>اشتراک</value>\n  </data>\n  <data name=\"LvEnabled\" xml:space=\"preserve\">\n    <value>به روز رسانی فعال شد</value>\n  </data>\n  <data name=\"LvSort\" xml:space=\"preserve\">\n    <value>مرتب سازی</value>\n  </data>\n  <data name=\"LvUserAgent\" xml:space=\"preserve\">\n    <value>عامل کاربر</value>\n  </data>\n  <data name=\"TbCancel\" xml:space=\"preserve\">\n    <value>لغو</value>\n  </data>\n  <data name=\"TbConfirm\" xml:space=\"preserve\">\n    <value>تایید</value>\n  </data>\n  <data name=\"GbTransport\" xml:space=\"preserve\">\n    <value>انتقال</value>\n  </data>\n  <data name=\"TbAddress\" xml:space=\"preserve\">\n    <value>آدرس</value>\n  </data>\n  <data name=\"TbAllowInsecure\" xml:space=\"preserve\">\n    <value>اجازه ناامن</value>\n  </data>\n  <data name=\"TbAlpn\" xml:space=\"preserve\">\n    <value>Alpn</value>\n  </data>\n  <data name=\"TbAlterId\" xml:space=\"preserve\">\n    <value>AlterId</value>\n  </data>\n  <data name=\"TbFingerprint\" xml:space=\"preserve\">\n    <value>Fingerprint</value>\n  </data>\n  <data name=\"TbHeaderType\" xml:space=\"preserve\">\n    <value>Camouflage type</value>\n  </data>\n  <data name=\"TbId\" xml:space=\"preserve\">\n    <value>UUID(id)</value>\n  </data>\n  <data name=\"TbNetwork\" xml:space=\"preserve\">\n    <value>پروتکل جابجایی (شبکه)</value>\n  </data>\n  <data name=\"TbPath\" xml:space=\"preserve\">\n    <value>مسیر</value>\n  </data>\n  <data name=\"TbPort\" xml:space=\"preserve\">\n    <value>پورت</value>\n  </data>\n  <data name=\"TbRemarks\" xml:space=\"preserve\">\n    <value>Alias (remarks)</value>\n  </data>\n  <data name=\"TbRequestHost\" xml:space=\"preserve\">\n    <value>Camouflage domain(host)</value>\n  </data>\n  <data name=\"TbSecurity\" xml:space=\"preserve\">\n    <value>Encryption method (security)</value>\n  </data>\n  <data name=\"TbSNI\" xml:space=\"preserve\">\n    <value>SNI</value>\n  </data>\n  <data name=\"TbStreamSecurity\" xml:space=\"preserve\">\n    <value>TLS</value>\n  </data>\n  <data name=\"TipNetwork\" xml:space=\"preserve\">\n    <value>Default value tcp</value>\n  </data>\n  <data name=\"TbCoreType\" xml:space=\"preserve\">\n    <value>نوع هسته</value>\n  </data>\n  <data name=\"TbFlow5\" xml:space=\"preserve\">\n    <value>جریان</value>\n  </data>\n  <data name=\"TbGUID\" xml:space=\"preserve\">\n    <value>Generate</value>\n  </data>\n  <data name=\"TbId3\" xml:space=\"preserve\">\n    <value>رمزعبور</value>\n  </data>\n  <data name=\"TbId4\" xml:space=\"preserve\">\n    <value>رمز عبور (اختیاری)</value>\n  </data>\n  <data name=\"TbId5\" xml:space=\"preserve\">\n    <value>UUID(id)</value>\n  </data>\n  <data name=\"TbSecurity3\" xml:space=\"preserve\">\n    <value>رمزگذاری</value>\n  </data>\n  <data name=\"TbSecurity4\" xml:space=\"preserve\">\n    <value>کاربر (اختیاری)</value>\n  </data>\n  <data name=\"TbSecurity5\" xml:space=\"preserve\">\n    <value>رمزگذاری</value>\n  </data>\n  <data name=\"TbPreSocksPort\" xml:space=\"preserve\">\n    <value>txtPreSocksPort</value>\n  </data>\n  <data name=\"TipPreSocksPort\" xml:space=\"preserve\">\n    <value>* After setting this value, an socks service will be started using Sing-box to provide functions such as speed display</value>\n  </data>\n  <data name=\"TbBrowse\" xml:space=\"preserve\">\n    <value>Browse</value>\n  </data>\n  <data name=\"TbEdit\" xml:space=\"preserve\">\n    <value>ویرایش</value>\n  </data>\n  <data name=\"TbSettingsAdvancedProtocol\" xml:space=\"preserve\">\n    <value>تنظیمات پیشرفته پروکسی، انتخاب پروتکل (اختیاری)</value>\n  </data>\n  <data name=\"TbSettingsAllowLAN\" xml:space=\"preserve\">\n    <value>اتصالات از LAN را مجاز کنید</value>\n  </data>\n  <data name=\"TbSettingsAutoHideStartup\" xml:space=\"preserve\">\n    <value>Auto hide startup</value>\n  </data>\n  <data name=\"TbSettingsAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>فاصله به روز رسانی خودکار و Geo (ساعت)</value>\n  </data>\n  <data name=\"TbSettingsCore\" xml:space=\"preserve\">\n    <value>هسته: تنظیمات اولیه</value>\n  </data>\n  <data name=\"TbSettingsCoreDns\" xml:space=\"preserve\">\n    <value>V2ray DNS settings</value>\n  </data>\n  <data name=\"TbSettingsCoreKcp\" xml:space=\"preserve\">\n    <value>هسته: تنظیمات KCP</value>\n  </data>\n  <data name=\"TbSettingsCoreType\" xml:space=\"preserve\">\n    <value>تنظیمات CoreType</value>\n  </data>\n  <data name=\"TbSettingsDefAllowInsecure\" xml:space=\"preserve\">\n    <value>اجازه ناامن</value>\n  </data>\n  <data name=\"TbSettingsDomainStrategy4Freedom\" xml:space=\"preserve\">\n    <value>Outbound Freedom domainStrategy</value>\n  </data>\n  <data name=\"TbSettingsEnableAutoAdjustMainLvColWidth\" xml:space=\"preserve\">\n    <value>پس از به‌روزرسانی اشتراک، عرض ستون را به صورت خودکار تنظیم شود</value>\n  </data>\n  <data name=\"TbSettingsEnableCheckPreReleaseUpdate\" xml:space=\"preserve\">\n    <value>به روز رسانی های پیش از انتشار را بررسی شود</value>\n  </data>\n  <data name=\"TbSettingsException\" xml:space=\"preserve\">\n    <value>استثنا</value>\n  </data>\n  <data name=\"TbSettingsExceptionTip\" xml:space=\"preserve\">\n    <value>Exception. Do not use proxy server for addresses beginning with,Use semicolon (;)</value>\n  </data>\n  <data name=\"TbSettingsHttpPort\" xml:space=\"preserve\">\n    <value>پورت Http</value>\n  </data>\n  <data name=\"TbSettingsIgnoreGeoUpdateCore\" xml:space=\"preserve\">\n    <value>هنگام به‌روزرسانی هسته، فایل‌های Geo را نادیده بگیرید</value>\n  </data>\n  <data name=\"TbSettingsKeepOlderDedupl\" xml:space=\"preserve\">\n    <value>Keep older when deduplication</value>\n  </data>\n  <data name=\"TbSettingsLogEnabled\" xml:space=\"preserve\">\n    <value>ثبت گزارش های محلی</value>\n  </data>\n  <data name=\"TbSettingsLogLevel\" xml:space=\"preserve\">\n    <value>سطح ثبت رویداد</value>\n  </data>\n  <data name=\"TbSettingsMuxEnabled\" xml:space=\"preserve\">\n    <value>Turn on Mux Multiplexing</value>\n  </data>\n  <data name=\"TbSettingsN\" xml:space=\"preserve\">\n    <value>تنظیمات v2rayN</value>\n  </data>\n  <data name=\"TbSettingsPass\" xml:space=\"preserve\">\n    <value>Auth pass</value>\n  </data>\n  <data name=\"TbSettingsRemoteDNS\" xml:space=\"preserve\">\n    <value>سفارشی DNS (multiple, separated by commas (,))</value>\n  </data>\n  <data name=\"TbSettingsSetUWP\" xml:space=\"preserve\">\n    <value>Set Win10 UWP Loopback</value>\n  </data>\n  <data name=\"TbSettingsSniffingEnabled\" xml:space=\"preserve\">\n    <value>Turn on Sniffing</value>\n  </data>\n  <data name=\"TbSettingsSocksPort\" xml:space=\"preserve\">\n    <value>ساکس Port</value>\n  </data>\n  <data name=\"TbSettingsStartBoot\" xml:space=\"preserve\">\n    <value>درهنگام راه ائدازی شروع شود</value>\n  </data>\n  <data name=\"TbSettingsStatistics\" xml:space=\"preserve\">\n    <value>فعال کردن آمار (نیاز به راه اندازی مجدد)</value>\n  </data>\n  <data name=\"TbSettingsStatisticsFreshRate\" xml:space=\"preserve\">\n    <value>نرخ تازه سازی آمار (ثانیه)</value>\n  </data>\n  <data name=\"TbSettingsSubConvert\" xml:space=\"preserve\">\n    <value>Subscription conversion Url</value>\n  </data>\n  <data name=\"TbSettingsSystemproxy\" xml:space=\"preserve\">\n    <value>تنظیمات پراکسی سیستم</value>\n  </data>\n  <data name=\"TbSettingsTLS13\" xml:space=\"preserve\">\n    <value>Enable Security Protocol TLS v1.3 (subscription/update)</value>\n  </data>\n  <data name=\"TbSettingsTrayMenuServersLimit\" xml:space=\"preserve\">\n    <value>Tray right-click menu servers display limit</value>\n  </data>\n  <data name=\"TbSettingsUdpEnabled\" xml:space=\"preserve\">\n    <value>UDP را فعال شود</value>\n  </data>\n  <data name=\"TbSettingsUser\" xml:space=\"preserve\">\n    <value>Auth user</value>\n  </data>\n  <data name=\"TbClearSystemProxy\" xml:space=\"preserve\">\n    <value>پاک کردن پروکسی سیستم</value>\n  </data>\n  <data name=\"TbDisplayGUI\" xml:space=\"preserve\">\n    <value>نمایش رابط کاربری گرافیکی</value>\n  </data>\n  <data name=\"TbGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>تنظیم کلید میانبر جهانی</value>\n  </data>\n  <data name=\"TbGlobalHotkeySettingTip\" xml:space=\"preserve\">\n    <value>مستقیماً با فشار دادن صفحه کلید تنظیم کنید، بعد از راه اندازی مجدد اعمال شود</value>\n  </data>\n  <data name=\"TbNotChangeSystemProxy\" xml:space=\"preserve\">\n    <value>پروکسی سیستم را تغییر ندهید</value>\n  </data>\n  <data name=\"TbReset\" xml:space=\"preserve\">\n    <value>بازنشانی</value>\n  </data>\n  <data name=\"TbSetSystemProxy\" xml:space=\"preserve\">\n    <value>تنظیم پراکسی سیستم</value>\n  </data>\n  <data name=\"TbSystemProxyPac\" xml:space=\"preserve\">\n    <value>حالت Pac</value>\n  </data>\n  <data name=\"menuShareServer\" xml:space=\"preserve\">\n    <value>اشتراک گذاری سرور(Ctrl+F)</value>\n  </data>\n  <data name=\"menuRouting\" xml:space=\"preserve\">\n    <value>مسیریابی</value>\n  </data>\n  <data name=\"NotRunAsAdmin\" xml:space=\"preserve\">\n    <value>به عنوان ادمین اجرا نمی شود</value>\n  </data>\n  <data name=\"RunAsAdmin\" xml:space=\"preserve\">\n    <value>اجرا به عنوان ادمین</value>\n  </data>\n  <data name=\"menuMoveBottom\" xml:space=\"preserve\">\n    <value>به پایین حرکت شود(B)</value>\n  </data>\n  <data name=\"menuMoveDown\" xml:space=\"preserve\">\n    <value>پایین (D)</value>\n  </data>\n  <data name=\"menuMoveTop\" xml:space=\"preserve\">\n    <value>Move to top (T)</value>\n  </data>\n  <data name=\"menuMoveUp\" xml:space=\"preserve\">\n    <value>Up (U)</value>\n  </data>\n  <data name=\"MsgFilterTitle\" xml:space=\"preserve\">\n    <value>Filter, support regular</value>\n  </data>\n  <data name=\"menuWebsiteItem\" xml:space=\"preserve\">\n    <value>{0} Website</value>\n  </data>\n  <data name=\"menuRoutingAdvanced\" xml:space=\"preserve\">\n    <value>عملکرد پیشرفته</value>\n  </data>\n  <data name=\"menuRoutingAdvancedAdd\" xml:space=\"preserve\">\n    <value>اضافه کردن</value>\n  </data>\n  <data name=\"menuRoutingAdvancedImportRules\" xml:space=\"preserve\">\n    <value>وارد کردن قوانین پیشرفته</value>\n  </data>\n  <data name=\"menuRoutingAdvancedRemove\" xml:space=\"preserve\">\n    <value>حذف انتخاب شده</value>\n  </data>\n  <data name=\"menuRoutingAdvancedSetDefault\" xml:space=\"preserve\">\n    <value>Set as active rule</value>\n  </data>\n  <data name=\"menuRoutingBasic\" xml:space=\"preserve\">\n    <value>عملکرد پایه</value>\n  </data>\n  <data name=\"menuRoutingBasicImportRules\" xml:space=\"preserve\">\n    <value>واردات قوانین اساسی</value>\n  </data>\n  <data name=\"TbdomainMatcher\" xml:space=\"preserve\">\n    <value>تطبیق دامنه</value>\n  </data>\n  <data name=\"TbdomainStrategy\" xml:space=\"preserve\">\n    <value>استراتژی دامنه</value>\n  </data>\n  <data name=\"TbenableRoutingAdvanced\" xml:space=\"preserve\">\n    <value>فعال کردن عملکرد پیشرفته</value>\n  </data>\n  <data name=\"TbRoutingTabBlock\" xml:space=\"preserve\">\n    <value>3.Block Domain or IP</value>\n  </data>\n  <data name=\"TbRoutingTabDirect\" xml:space=\"preserve\">\n    <value>2.Direct Domain or IP</value>\n  </data>\n  <data name=\"TbRoutingTabProxy\" xml:space=\"preserve\">\n    <value>1.Proxy Domain or IP</value>\n  </data>\n  <data name=\"TbRoutingTabRuleList\" xml:space=\"preserve\">\n    <value>لیست مجموعه قوانین از پیش تعریف شده</value>\n  </data>\n  <data name=\"TbRoutingTips\" xml:space=\"preserve\">\n    <value>*Set the rules, separated by commas (,); The comma in the regular is replaced by &lt;COMMA&gt;</value>\n  </data>\n  <data name=\"menuImportRulesFromClipboard\" xml:space=\"preserve\">\n    <value>وارد کردن قوانین از کلیپ بورد</value>\n  </data>\n  <data name=\"menuImportRulesFromFile\" xml:space=\"preserve\">\n    <value>وارد کردن قوانین از فایل</value>\n  </data>\n  <data name=\"menuImportRulesFromUrl\" xml:space=\"preserve\">\n    <value>وارد کردن قوانین از Sub Url</value>\n  </data>\n  <data name=\"menuRoutingRuleSetting\" xml:space=\"preserve\">\n    <value>تنظیم قانون</value>\n  </data>\n  <data name=\"menuRuleAdd\" xml:space=\"preserve\">\n    <value>اضافه کردن قانون</value>\n  </data>\n  <data name=\"menuRuleExportSelected\" xml:space=\"preserve\">\n    <value>صادر کردن قوانین انتخاب شده</value>\n  </data>\n  <data name=\"menuRuleList\" xml:space=\"preserve\">\n    <value>فهرست قوانین</value>\n  </data>\n  <data name=\"menuRuleRemove\" xml:space=\"preserve\">\n    <value>حذف قوانین</value>\n  </data>\n  <data name=\"menuRoutingRuleDetailsSetting\" xml:space=\"preserve\">\n    <value>تنظیم جزئیات قانون مسیریابی</value>\n  </data>\n  <data name=\"TbAutoSort\" xml:space=\"preserve\">\n    <value>دامنه و آی پی در هنگام ذخیره به طور خودکار مرتب می شوند</value>\n  </data>\n  <data name=\"TbRuleobjectDoc\" xml:space=\"preserve\">\n    <value>Ruleobject Doc</value>\n  </data>\n  <data name=\"TbDnsObjectDoc\" xml:space=\"preserve\">\n    <value>پشتیبانی از DnsObject</value>\n  </data>\n  <data name=\"SubUrlTips\" xml:space=\"preserve\">\n    <value>گروه لطفا اینجا را خالی بگذارید</value>\n  </data>\n  <data name=\"TipChangeRouting\" xml:space=\"preserve\">\n    <value>تنظیمات مسیریابی تغییر کرده است</value>\n  </data>\n  <data name=\"TipChangeSystemProxy\" xml:space=\"preserve\">\n    <value>تنظیمات پراکسی سیستم تغییر کرده است</value>\n  </data>\n  <data name=\"TbSettingsRouteOnly\" xml:space=\"preserve\">\n    <value>فقط مسیر</value>\n  </data>\n  <data name=\"menuMixedTestServer\" xml:space=\"preserve\">\n    <value>One-click test Latency and speed (Ctrl+E)</value>\n  </data>\n  <data name=\"LvTestDelay\" xml:space=\"preserve\">\n    <value>تاخیر (میلی‌ثانیه)</value>\n  </data>\n  <data name=\"LvTestSpeed\" xml:space=\"preserve\">\n    <value>Speed(M/s)</value>\n  </data>\n  <data name=\"FailedToRunCore\" xml:space=\"preserve\">\n    <value>Core اجرا نشد، لطفاً گزارش را ببینید</value>\n  </data>\n  <data name=\"LvFilter\" xml:space=\"preserve\">\n    <value>Remarks regular filter</value>\n  </data>\n  <data name=\"TbDisplayLog\" xml:space=\"preserve\">\n    <value>نمایش گزارش</value>\n  </data>\n  <data name=\"menuImportOldGuiConfig\" xml:space=\"preserve\">\n    <value>پیکربندی قدیمی guiNConfig را وارد شود</value>\n  </data>\n  <data name=\"TbEnableTunAs\" xml:space=\"preserve\">\n    <value>Tun را فعال شود</value>\n  </data>\n  <data name=\"TbSettingsNewPort4LAN\" xml:space=\"preserve\">\n    <value>پورت جدید برای LAN</value>\n  </data>\n  <data name=\"TbSettingsTunMode\" xml:space=\"preserve\">\n    <value>تنظیمات TunMode</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectIP\" xml:space=\"preserve\">\n    <value>Direct IP CIDR, separated by commas (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectProcess\" xml:space=\"preserve\">\n    <value>Direct Process name, separated by commas (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeShowWindow\" xml:space=\"preserve\">\n    <value>نمایش کنسول</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgent\" xml:space=\"preserve\">\n    <value>User-Agent</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgentTips\" xml:space=\"preserve\">\n    <value>This parameter is valid only for tcp/http and ws</value>\n  </data>\n  <data name=\"TbSettingsEnableHWA\" xml:space=\"preserve\">\n    <value>فعال‌سازی شتاب‌دهنده سخت‌افزاری (نیاز به راه‌اندازی مجدد)</value>\n  </data>\n  <data name=\"TbEnableProxy\" xml:space=\"preserve\">\n    <value>فعال کردن پروکسی</value>\n  </data>\n  <data name=\"RoutingAllSites\" xml:space=\"preserve\">\n    <value>همه سایت‌ها</value>\n  </data>\n  <data name=\"RoutingBlockedSites\" xml:space=\"preserve\">\n    <value>سایت‌های فیلترشده</value>\n  </data>\n  <data name=\"RoutingForeignSites\" xml:space=\"preserve\">\n    <value>سایت‌های خارجی</value>\n  </data>\n</root>"
  },
  {
    "path": "v2rayN/v2rayN/Resx/ResUI.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=\"BatchExportSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>Batch export subscription to clipboard successfully</value>\n  </data>\n  <data name=\"BatchExportURLSuccessfully\" xml:space=\"preserve\">\n    <value>Batch export share URL to clipboard successfully</value>\n  </data>\n  <data name=\"CheckServerSettings\" xml:space=\"preserve\">\n    <value>Please check the server settings first</value>\n  </data>\n  <data name=\"ConfigurationFormatIncorrect\" xml:space=\"preserve\">\n    <value>Invalid configuration format</value>\n  </data>\n  <data name=\"CustomServerTips\" xml:space=\"preserve\">\n    <value>Note that custom configuration relies entirely on your own configuration and does not work with all settings. If you want to use the system proxy, please modify the listening port manually.</value>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Downloading...</value>\n  </data>\n  <data name=\"downloadSpeed\" xml:space=\"preserve\">\n    <value>Download</value>\n  </data>\n  <data name=\"DownloadYesNo\" xml:space=\"preserve\">\n    <value>Whether to download? {0}</value>\n  </data>\n  <data name=\"FailedConversionConfiguration\" xml:space=\"preserve\">\n    <value>Failed to convert configuration file</value>\n  </data>\n  <data name=\"FailedGenDefaultConfiguration\" xml:space=\"preserve\">\n    <value>Failed to generate default configuration file</value>\n  </data>\n  <data name=\"FailedGetDefaultConfiguration\" xml:space=\"preserve\">\n    <value> Failed to get the default configuration</value>\n  </data>\n  <data name=\"FailedImportedCustomServer\" xml:space=\"preserve\">\n    <value>Failed to import custom configuration server</value>\n  </data>\n  <data name=\"FailedReadConfiguration\" xml:space=\"preserve\">\n    <value>Failed to read configuration file</value>\n  </data>\n  <data name=\"FillCorrectServerPort\" xml:space=\"preserve\">\n    <value>Please fill in the correct format server port</value>\n  </data>\n  <data name=\"FillKcpParameters\" xml:space=\"preserve\">\n    <value>Please fill in the KCP parameters correctly</value>\n  </data>\n  <data name=\"FillLocalListeningPort\" xml:space=\"preserve\">\n    <value>Please fill in the local listening port</value>\n  </data>\n\n  <data name=\"HomeImport\" xml:space=\"preserve\">\n    <value>Import</value>\n  </data>\n  <data name=\"HomeDelete\" xml:space=\"preserve\">\n    <value>Delete</value>\n  </data>\n  <data name=\"HomeWelcomeMsg\" xml:space=\"preserve\">\n    <value>Welcome to the Hiddify</value>\n  </data>\n  <data name=\"HomeUsage\" xml:space=\"preserve\">\n    <value>Usage</value>\n  </data>\n  <data name=\"HomeDays\" xml:space=\"preserve\">\n    <value>Days</value>\n  </data>\n  <data name=\"HomeConnected\" xml:space=\"preserve\">\n    <value>Connected</value>\n  </data>\n  <data name=\"HomeProxyAuto\" xml:space=\"preserve\">\n    <value>Auto</value>\n  </data>\n  <data name=\"HomeProxyLoadBalance\" xml:space=\"preserve\">\n    <value>Load Balance</value>\n  </data>\n  <data name=\"HomeProxyManual\" xml:space=\"preserve\">\n    <value>Manual</value>\n  </data>\n  <data name=\"HomeNotConnected\" xml:space=\"preserve\">\n    <value>Not Connected</value>\n  </data>\n  <data name=\"HomeDisconnected\" xml:space=\"preserve\">\n    <value>Disconnected</value>\n  </data>\n  <data name=\"HomeRemaining\" xml:space=\"preserve\">\n    <value>Remaining</value>\n  </data>\n  <data name=\"HomeDelay\" xml:space=\"preserve\">\n    <value>Delay</value>\n  </data>\n  <data name=\"HomeConnecting\" xml:space=\"preserve\">\n    <value>Connecting...</value>\n  </data>\n  <data name=\"HomeProxyModeSelection\" xml:space=\"preserve\">\n    <value>Proxy Mode Selection</value>\n  </data>\n  <data name=\"HomeAdvancedSettings\" xml:space=\"preserve\">\n    <value>Advanced Settings</value>\n  </data>\n  <data name=\"MsgInformationTitle\" xml:space=\"preserve\">\n    <value>ّInformation</value>\n  </data>\n  <data name=\"LvCustomIcon\" xml:space=\"preserve\">\n    <value>نماد سفارشی</value>\n  </data>\n  <data name=\"FillCorrectDNSText\" xml:space=\"preserve\">\n    <value>لطفاً DNS سفارشی صحیح را پر کنید</value>\n  </data>\n\n  <data name=\"FillPassword\" xml:space=\"preserve\">\n    <value>Please fill in the password</value>\n  </data>\n  <data name=\"FillServerAddress\" xml:space=\"preserve\">\n    <value>Please fill in the server address</value>\n  </data>\n  <data name=\"FillUUID\" xml:space=\"preserve\">\n    <value>Please fill in the user ID</value>\n  </data>\n  <data name=\"IncorrectClientConfiguration\" xml:space=\"preserve\">\n    <value> is not the correct client configuration file, please check</value>\n  </data>\n  <data name=\"Incorrectconfiguration\" xml:space=\"preserve\">\n    <value> is not the correct configuration, please check</value>\n  </data>\n  <data name=\"IncorrectServerConfiguration\" xml:space=\"preserve\">\n    <value> is not the correct server configuration file, please check</value>\n  </data>\n  <data name=\"InitialConfiguration\" xml:space=\"preserve\">\n    <value>Initial Configuration</value>\n  </data>\n  <data name=\"IsLatestCore\" xml:space=\"preserve\">\n    <value>{0} already up to date.</value>\n  </data>\n  <data name=\"IsLatestN\" xml:space=\"preserve\">\n    <value>{0} already up to date.</value>\n  </data>\n  <data name=\"LvAddress\" xml:space=\"preserve\">\n    <value>Address</value>\n  </data>\n  <data name=\"LvEncryptionMethod\" xml:space=\"preserve\">\n    <value>Security</value>\n  </data>\n  <data name=\"LvPort\" xml:space=\"preserve\">\n    <value>Port</value>\n  </data>\n  <data name=\"LvServiceType\" xml:space=\"preserve\">\n    <value>Type</value>\n  </data>\n  <data name=\"LvSubscription\" xml:space=\"preserve\">\n    <value>Subs group</value>\n  </data>\n  <data name=\"LvTodayDownloadDataAmount\" xml:space=\"preserve\">\n    <value>Download traffic today</value>\n  </data>\n  <data name=\"LvTodayUploadDataAmount\" xml:space=\"preserve\">\n    <value>Upload traffic today</value>\n  </data>\n  <data name=\"LvTotalDownloadDataAmount\" xml:space=\"preserve\">\n    <value>Total download traffic</value>\n  </data>\n  <data name=\"LvTotalUploadDataAmount\" xml:space=\"preserve\">\n    <value>Total upload traffic</value>\n  </data>\n  <data name=\"LvTransportProtocol\" xml:space=\"preserve\">\n    <value>Transport</value>\n  </data>\n  <data name=\"MsgClearSubscription\" xml:space=\"preserve\">\n    <value>Clear original subscription content</value>\n  </data>\n  <data name=\"MsgDownloadV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>Download Core successfully</value>\n  </data>\n  <data name=\"MsgFailedImportSubscription\" xml:space=\"preserve\">\n    <value>Failed to import subscription content</value>\n  </data>\n  <data name=\"MsgGetSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>Get subscription content successfully</value>\n  </data>\n  <data name=\"MsgNoValidSubscription\" xml:space=\"preserve\">\n    <value>No valid subscriptions set</value>\n  </data>\n  <data name=\"MsgParsingSuccessfully\" xml:space=\"preserve\">\n    <value>Resolve {0} successfully</value>\n  </data>\n  <data name=\"MsgStartGettingSubscriptions\" xml:space=\"preserve\">\n    <value>Start getting subscriptions</value>\n  </data>\n  <data name=\"MsgStartUpdating\" xml:space=\"preserve\">\n    <value>Start updating {0}...</value>\n  </data>\n  <data name=\"MsgSubscriptionDecodingFailed\" xml:space=\"preserve\">\n    <value>Invalid subscription content</value>\n  </data>\n  <data name=\"MsgUnpacking\" xml:space=\"preserve\">\n    <value>is unpacking...</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionEnd\" xml:space=\"preserve\">\n    <value>Update subscription end</value>\n  </data>\n  <data name=\"MsgNothingUpdated\" xml:space=\"preserve\">\n    <value>Nothing has been Updated</value>\n  </data>\n  <data name=\"MsgStartProgramAsAdmin\" xml:space=\"preserve\">\n    <value>To do this, the program must be run in Administrator mode</value>\n  </data>\n  <data name=\"MsgDeepLinkIsInvalid\" xml:space=\"preserve\">\n    <value>The link is invalid</value>\n  </data>\n  <data name=\"MsgProgramNeedsRestarting\" xml:space=\"preserve\">\n    <value>To perform this operation, the program must be restarted !</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionStart\" xml:space=\"preserve\">\n    <value>Update subscription starts</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>Update Core successfully</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfullyMore\" xml:space=\"preserve\">\n    <value>Update Core successfully! Restarting service...</value>\n  </data>\n  <data name=\"NonvmessOrssProtocol\" xml:space=\"preserve\">\n    <value>Non-VMess or ss protocol</value>\n  </data>\n  <data name=\"NonVmessService\" xml:space=\"preserve\">\n    <value> non-standard service, this feature is invalid</value>\n  </data>\n  <data name=\"NotFoundCore\" xml:space=\"preserve\">\n    <value>The Core file (file name: {1}) was not found under the folder ({0}), please download and put it in the folder, download address: {2}</value>\n  </data>\n  <data name=\"NoValidQRcodeFound\" xml:space=\"preserve\">\n    <value>Scan completed, no valid QR code found</value>\n  </data>\n  <data name=\"OperationFailed\" xml:space=\"preserve\">\n    <value> operation failed, please check and retry</value>\n  </data>\n  <data name=\"PleaseFillRemarks\" xml:space=\"preserve\">\n    <value>Please Fill Remarks</value>\n  </data>\n  <data name=\"PleaseSelectEncryption\" xml:space=\"preserve\">\n    <value>Please select the encryption method</value>\n  </data>\n  <data name=\"PleaseSelectProtocol\" xml:space=\"preserve\">\n    <value>Please select a protocol</value>\n  </data>\n  <data name=\"PleaseSelectServer\" xml:space=\"preserve\">\n    <value>Please select the server first</value>\n  </data>\n  <data name=\"RemoveDuplicateServerResult\" xml:space=\"preserve\">\n    <value>Servers deduplication completed. Old: {0}, New: {1}.</value>\n  </data>\n  <data name=\"RemoveServer\" xml:space=\"preserve\">\n    <value>Are you sure to remove the server?</value>\n  </data>\n  <data name=\"SaveClientConfigurationIn\" xml:space=\"preserve\">\n    <value>The client configuration file is saved at: {0}</value>\n  </data>\n  <data name=\"StartService\" xml:space=\"preserve\">\n    <value>Start service ({0})...</value>\n  </data>\n  <data name=\"SuccessfulConfiguration\" xml:space=\"preserve\">\n    <value>Configuration successful\n{0}</value>\n  </data>\n  <data name=\"SuccessfullyImportedCustomServer\" xml:space=\"preserve\">\n    <value>Custom configuration server imported successfully.</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaClipboard\" xml:space=\"preserve\">\n    <value>{0} servers have been imported from clipboard.</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaScan\" xml:space=\"preserve\">\n    <value>Scan import URL successfully</value>\n  </data>\n  <data name=\"TestMeOutput\" xml:space=\"preserve\">\n    <value>The ping of current service: {0} ms</value>\n  </data>\n  <data name=\"OperationSuccess\" xml:space=\"preserve\">\n    <value>Operation success</value>\n  </data>\n  <data name=\"PleaseSelectRules\" xml:space=\"preserve\">\n    <value>Please select rules</value>\n  </data>\n  <data name=\"RemoveRules\" xml:space=\"preserve\">\n    <value>Are you sure to remove the rules?</value>\n  </data>\n  <data name=\"RoutingRuleDetailRequiredTips\" xml:space=\"preserve\">\n    <value>{0},One of the required.</value>\n  </data>\n  <data name=\"LvRemarks\" xml:space=\"preserve\">\n    <value>Remarks</value>\n  </data>\n  <data name=\"HomeDelay\" xml:space=\"preserve\">\n    <value>Delay</value>\n  </data>\n  <data name=\"LvUrl\" xml:space=\"preserve\">\n    <value>Url(Optional)</value>\n  </data>\n  <data name=\"LvCount\" xml:space=\"preserve\">\n    <value>Count</value>\n  </data>\n  <data name=\"MsgNeedUrl\" xml:space=\"preserve\">\n    <value>Please fill in the Url</value>\n  </data>\n  <data name=\"AddBatchRoutingRulesYesNo\" xml:space=\"preserve\">\n    <value>Do you want to append rules? Choose yes to append, choose otherwise to replace</value>\n  </data>\n  <data name=\"MsgDownloadGeoFileSuccessfully\" xml:space=\"preserve\">\n    <value>Download GeoFile: {0} successfully</value>\n  </data>\n  <data name=\"MsgInformationTitle\" xml:space=\"preserve\">\n    <value>Information</value>\n  </data>\n  <data name=\"LvCustomIcon\" xml:space=\"preserve\">\n    <value>Custom Icon</value>\n  </data>\n  <data name=\"FillCorrectDNSText\" xml:space=\"preserve\">\n    <value>Please fill in the correct custom DNS</value>\n  </data>\n  <data name=\"TransportPathTip1\" xml:space=\"preserve\">\n    <value>*ws path</value>\n  </data>\n  <data name=\"TransportPathTip2\" xml:space=\"preserve\">\n    <value>*h2 path</value>\n  </data>\n  <data name=\"TransportPathTip3\" xml:space=\"preserve\">\n    <value>*QUIC key/Kcp seed</value>\n  </data>\n  <data name=\"TransportPathTip4\" xml:space=\"preserve\">\n    <value>*grpc serviceName</value>\n  </data>\n  <data name=\"TransportRequestHostTip1\" xml:space=\"preserve\">\n    <value>*http host Separated by commas (,)</value>\n  </data>\n  <data name=\"TransportRequestHostTip2\" xml:space=\"preserve\">\n    <value>*ws host</value>\n  </data>\n  <data name=\"TransportRequestHostTip3\" xml:space=\"preserve\">\n    <value>*h2 host Separated by commas (,)</value>\n  </data>\n  <data name=\"TransportRequestHostTip4\" xml:space=\"preserve\">\n    <value>*QUIC security</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip1\" xml:space=\"preserve\">\n    <value>*tcp camouflage type</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip2\" xml:space=\"preserve\">\n    <value>*kcp camouflage type</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip3\" xml:space=\"preserve\">\n    <value>*QUIC camouflage type</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip4\" xml:space=\"preserve\">\n    <value>*grpc mode</value>\n  </data>\n  <data name=\"LvTLS\" xml:space=\"preserve\">\n    <value>TLS</value>\n  </data>\n  <data name=\"TransportPathTip5\" xml:space=\"preserve\">\n    <value>*Kcp seed</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeyFailed\" xml:space=\"preserve\">\n    <value>Global hotkey {0} registered failed, reason {1}</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeySuccessfully\" xml:space=\"preserve\">\n    <value>Global hotkey {0} registered successfully</value>\n  </data>\n  <data name=\"UngroupedServers\" xml:space=\"preserve\">\n    <value>Ungrouped</value>\n  </data>\n  <data name=\"AllGroupServers\" xml:space=\"preserve\">\n    <value>All</value>\n  </data>\n  <data name=\"FillServerAddressCustom\" xml:space=\"preserve\">\n    <value>Please browse to import server configuration</value>\n  </data>\n  <data name=\"SystemProxy\" xml:space=\"preserve\">\n    <value>System proxy</value>\n  </data>\n  <data name=\"Speedtesting\" xml:space=\"preserve\">\n    <value>Testing...</value>\n  </data>\n  <data name=\"TooManyServersTip\" xml:space=\"preserve\">\n    <value>Too many servers, please open the main interface</value>\n  </data>\n  <data name=\"LabLAN\" xml:space=\"preserve\">\n    <value>LAN</value>\n  </data>\n  <data name=\"LabLocal\" xml:space=\"preserve\">\n    <value>Local</value>\n  </data>\n  <data name=\"MsgServerTitle\" xml:space=\"preserve\">\n    <value>Servers Filter, press Enter to execute</value>\n  </data>\n  <data name=\"menuCheckUpdate\" xml:space=\"preserve\">\n    <value>Check Update</value>\n  </data>\n  <data name=\"menuClose\" xml:space=\"preserve\">\n    <value>Close</value>\n  </data>\n  <data name=\"menuExit\" xml:space=\"preserve\">\n    <value>Exit</value>\n  </data>\n  <data name=\"menuGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>GlobalHotkeySetting</value>\n  </data>\n  <data name=\"menuHelp\" xml:space=\"preserve\">\n    <value>Help</value>\n  </data>\n  <data name=\"menuOptionSetting\" xml:space=\"preserve\">\n    <value>Option Setting</value>\n  </data>\n  <data name=\"menuPromotion\" xml:space=\"preserve\">\n    <value>Channel</value>\n  </data>\n  <data name=\"menuReload\" xml:space=\"preserve\">\n    <value>Reload</value>\n  </data>\n  <data name=\"menuRoutingSetting\" xml:space=\"preserve\">\n    <value>Routing Setting</value>\n  </data>\n  <data name=\"menuServers\" xml:space=\"preserve\">\n    <value>Servers</value>\n  </data>\n  <data name=\"menuSetting\" xml:space=\"preserve\">\n    <value>Settings</value>\n  </data>\n  <data name=\"menuSubGroupUpdate\" xml:space=\"preserve\">\n    <value>Update current subscription without proxy</value>\n  </data>\n  <data name=\"menuSubGroupUpdateViaProxy\" xml:space=\"preserve\">\n    <value>Update current subscription with proxy</value>\n  </data>\n  <data name=\"menuSubscription\" xml:space=\"preserve\">\n    <value>Subs group</value>\n  </data>\n  <data name=\"menuSubSetting\" xml:space=\"preserve\">\n    <value>Subscription group Settings</value>\n  </data>\n  <data name=\"menuSubUpdate\" xml:space=\"preserve\">\n    <value>Update subscription without proxy</value>\n  </data>\n  <data name=\"menuSubUpdateViaProxy\" xml:space=\"preserve\">\n    <value>Update subscription with proxy</value>\n  </data>\n  <data name=\"menuSystemproxy\" xml:space=\"preserve\">\n    <value>System proxy</value>\n  </data>\n  <data name=\"menuSystemProxyClear\" xml:space=\"preserve\">\n    <value>Clear system proxy</value>\n  </data>\n  <data name=\"menuSystemProxyNothing\" xml:space=\"preserve\">\n    <value>Do not change system proxy</value>\n  </data>\n  <data name=\"menuSystemProxyPac\" xml:space=\"preserve\">\n    <value>Pac Mode</value>\n  </data>\n  <data name=\"menuSystemProxySet\" xml:space=\"preserve\">\n    <value>Set system proxy</value>\n  </data>\n  <data name=\"TbSettingsColor\" xml:space=\"preserve\">\n    <value>Color</value>\n  </data>\n  <data name=\"TbSettingsColorMode\" xml:space=\"preserve\">\n    <value>Dark Mode</value>\n  </data>\n  <data name=\"TbSettingsLanguage\" xml:space=\"preserve\">\n    <value>Language(Restart)</value>\n  </data>\n  <data name=\"menuAddServerViaClipboard\" xml:space=\"preserve\">\n    <value>Import bulk URL from clipboard (Ctrl+V)</value>\n  </data>\n  <data name=\"menuAddServerViaScan\" xml:space=\"preserve\">\n    <value>Scan QR code on the screen (Ctrl+S)</value>\n  </data>\n  <data name=\"menuCopyServer\" xml:space=\"preserve\">\n    <value>Clone selected server</value>\n  </data>\n  <data name=\"menuRemoveDuplicateServer\" xml:space=\"preserve\">\n    <value>Remove duplicate servers</value>\n  </data>\n  <data name=\"menuRemoveServer\" xml:space=\"preserve\">\n    <value>Remove selected servers (Delete)</value>\n  </data>\n  <data name=\"menuSetDefaultServer\" xml:space=\"preserve\">\n    <value>Set as active server (Enter)</value>\n  </data>\n  <data name=\"menuClearServerStatistics\" xml:space=\"preserve\">\n    <value>Clear all service statistics</value>\n  </data>\n  <data name=\"menuPingServer\" xml:space=\"preserve\">\n    <value>Test servers ping (Ctrl+P)</value>\n  </data>\n  <data name=\"menuRealPingServer\" xml:space=\"preserve\">\n    <value>Test servers real delay (Ctrl+R)</value>\n  </data>\n  <data name=\"menuSortServerResult\" xml:space=\"preserve\">\n    <value>Sort by test result</value>\n  </data>\n  <data name=\"menuSpeedServer\" xml:space=\"preserve\">\n    <value>Test servers download speed (Ctrl+T)</value>\n  </data>\n  <data name=\"menuTcpingServer\" xml:space=\"preserve\">\n    <value>Test servers with tcping (Ctrl+O)</value>\n  </data>\n  <data name=\"menuTestMe\" xml:space=\"preserve\">\n    <value>Test current service status</value>\n  </data>\n  <data name=\"menuExport2ClientConfig\" xml:space=\"preserve\">\n    <value>Export selected server for client configuration</value>\n  </data>\n  <data name=\"menuExport2ShareUrl\" xml:space=\"preserve\">\n    <value>Export share URLs to clipboard (Ctrl+C)</value>\n  </data>\n  <data name=\"menuExport2SubContent\" xml:space=\"preserve\">\n    <value>Export subscription (base64) share to clipboard</value>\n  </data>\n  <data name=\"menuAddCustomServer\" xml:space=\"preserve\">\n    <value>Add a custom configuration server</value>\n  </data>\n  <data name=\"menuAddShadowsocksServer\" xml:space=\"preserve\">\n    <value>Add [Shadowsocks] server</value>\n  </data>\n  <data name=\"menuAddSocksServer\" xml:space=\"preserve\">\n    <value>Add [Socks] server</value>\n  </data>\n  <data name=\"menuAddTrojanServer\" xml:space=\"preserve\">\n    <value>Add [Trojan] server</value>\n  </data>\n  <data name=\"menuAddVlessServer\" xml:space=\"preserve\">\n    <value>Add [VLESS] server</value>\n  </data>\n  <data name=\"menuAddVmessServer\" xml:space=\"preserve\">\n    <value>Add [VMess] server</value>\n  </data>\n  <data name=\"menuSelectAll\" xml:space=\"preserve\">\n    <value>Select All (Ctrl+A)</value>\n  </data>\n  <data name=\"menuMsgViewClear\" xml:space=\"preserve\">\n    <value>Clear All</value>\n  </data>\n  <data name=\"menuMsgViewCopy\" xml:space=\"preserve\">\n    <value>Copy (Ctrl+C)</value>\n  </data>\n  <data name=\"menuMsgViewCopyAll\" xml:space=\"preserve\">\n    <value>Copy All</value>\n  </data>\n  <data name=\"menuMsgViewFilter\" xml:space=\"preserve\">\n    <value>Set message filters</value>\n  </data>\n  <data name=\"menuMsgViewSelectAll\" xml:space=\"preserve\">\n    <value>Select All (Ctrl+A)</value>\n  </data>\n  <data name=\"menuSubAdd\" xml:space=\"preserve\">\n    <value>Add</value>\n  </data>\n  <data name=\"menuSubDelete\" xml:space=\"preserve\">\n    <value>Delete</value>\n  </data>\n  <data name=\"menuSubEdit\" xml:space=\"preserve\">\n    <value>Edit</value>\n  </data>\n  <data name=\"menuSubShare\" xml:space=\"preserve\">\n    <value>Share</value>\n  </data>\n  <data name=\"LvEnabled\" xml:space=\"preserve\">\n    <value>Enabled Update</value>\n  </data>\n  <data name=\"LvSort\" xml:space=\"preserve\">\n    <value>Sort</value>\n  </data>\n  <data name=\"LvUserAgent\" xml:space=\"preserve\">\n    <value>User Agent</value>\n  </data>\n  <data name=\"TbCancel\" xml:space=\"preserve\">\n    <value>Cancel</value>\n  </data>\n  <data name=\"TbConfirm\" xml:space=\"preserve\">\n    <value>Confirm</value>\n  </data>\n  <data name=\"GbTransport\" xml:space=\"preserve\">\n    <value>Transport</value>\n  </data>\n  <data name=\"TbAddress\" xml:space=\"preserve\">\n    <value>Address</value>\n  </data>\n  <data name=\"TbAllowInsecure\" xml:space=\"preserve\">\n    <value>AllowInsecure</value>\n  </data>\n  <data name=\"TbAlpn\" xml:space=\"preserve\">\n    <value>Alpn</value>\n  </data>\n  <data name=\"TbAlterId\" xml:space=\"preserve\">\n    <value>AlterId</value>\n  </data>\n  <data name=\"TbFingerprint\" xml:space=\"preserve\">\n    <value>Fingerprint</value>\n  </data>\n  <data name=\"TbHeaderType\" xml:space=\"preserve\">\n    <value>Camouflage type</value>\n  </data>\n  <data name=\"TbId\" xml:space=\"preserve\">\n    <value>UUID(id)</value>\n  </data>\n  <data name=\"TbNetwork\" xml:space=\"preserve\">\n    <value>Transport protocol(network)</value>\n  </data>\n  <data name=\"TbPath\" xml:space=\"preserve\">\n    <value>Path</value>\n  </data>\n  <data name=\"TbPort\" xml:space=\"preserve\">\n    <value>Port</value>\n  </data>\n  <data name=\"TbRemarks\" xml:space=\"preserve\">\n    <value>Alias (remarks)</value>\n  </data>\n  <data name=\"TbRequestHost\" xml:space=\"preserve\">\n    <value>Camouflage domain(host)</value>\n  </data>\n  <data name=\"TbSecurity\" xml:space=\"preserve\">\n    <value>Encryption method (security)</value>\n  </data>\n  <data name=\"TbSNI\" xml:space=\"preserve\">\n    <value>SNI</value>\n  </data>\n  <data name=\"TbStreamSecurity\" xml:space=\"preserve\">\n    <value>TLS</value>\n  </data>\n  <data name=\"TipNetwork\" xml:space=\"preserve\">\n    <value>*Default value tcp</value>\n  </data>\n  <data name=\"TbCoreType\" xml:space=\"preserve\">\n    <value>Core Type</value>\n  </data>\n  <data name=\"TbFlow5\" xml:space=\"preserve\">\n    <value>Flow</value>\n  </data>\n  <data name=\"TbGUID\" xml:space=\"preserve\">\n    <value>Generate</value>\n  </data>\n  <data name=\"TbId3\" xml:space=\"preserve\">\n    <value>Password</value>\n  </data>\n  <data name=\"TbId4\" xml:space=\"preserve\">\n    <value>Password(Optional)</value>\n  </data>\n  <data name=\"TbId5\" xml:space=\"preserve\">\n    <value>UUID(id)</value>\n  </data>\n  <data name=\"TbSecurity3\" xml:space=\"preserve\">\n    <value>Encryption</value>\n  </data>\n  <data name=\"TbSecurity4\" xml:space=\"preserve\">\n    <value>User(Optional)</value>\n  </data>\n  <data name=\"TbSecurity5\" xml:space=\"preserve\">\n    <value>Encryption</value>\n  </data>\n  <data name=\"TbPreSocksPort\" xml:space=\"preserve\">\n    <value>txtPreSocksPort</value>\n  </data>\n  <data name=\"TipPreSocksPort\" xml:space=\"preserve\">\n    <value>* After setting this value, an socks service will be started using Sing-box to provide functions such as speed display</value>\n  </data>\n  <data name=\"TbBrowse\" xml:space=\"preserve\">\n    <value>Browse</value>\n  </data>\n  <data name=\"TbEdit\" xml:space=\"preserve\">\n    <value>Edit</value>\n  </data>\n  <data name=\"TbSettingsAdvancedProtocol\" xml:space=\"preserve\">\n    <value>Advanced proxy settings, protocol selection (optional)</value>\n  </data>\n  <data name=\"TbSettingsAllowLAN\" xml:space=\"preserve\">\n    <value>Allow connections from the LAN</value>\n  </data>\n  <data name=\"TbSettingsAutoHideStartup\" xml:space=\"preserve\">\n    <value>Auto hide startup</value>\n  </data>\n  <data name=\"TbSettingsAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Automatic update interval of Geo (hours)</value>\n  </data>\n  <data name=\"TbSettingsCore\" xml:space=\"preserve\">\n    <value>Core: basic settings</value>\n  </data>\n  <data name=\"TbSettingsCoreDns\" xml:space=\"preserve\">\n    <value>V2ray DNS settings</value>\n  </data>\n  <data name=\"TbSettingsCoreKcp\" xml:space=\"preserve\">\n    <value>Core: KCP settings</value>\n  </data>\n  <data name=\"TbSettingsCoreType\" xml:space=\"preserve\">\n    <value>CoreType settings</value>\n  </data>\n  <data name=\"TbSettingsDefAllowInsecure\" xml:space=\"preserve\">\n    <value>AllowInsecure</value>\n  </data>\n  <data name=\"TbSettingsDomainStrategy4Freedom\" xml:space=\"preserve\">\n    <value>Outbound Freedom domainStrategy</value>\n  </data>\n  <data name=\"TbSettingsEnableAutoAdjustMainLvColWidth\" xml:space=\"preserve\">\n    <value>Automatically adjust column width after updating subscription</value>\n  </data>\n  <data name=\"TbSettingsEnableCheckPreReleaseUpdate\" xml:space=\"preserve\">\n    <value>Check for pre-release updates</value>\n  </data>\n  <data name=\"TbSettingsException\" xml:space=\"preserve\">\n    <value>Exception</value>\n  </data>\n  <data name=\"TbSettingsExceptionTip\" xml:space=\"preserve\">\n    <value>Exception. Do not use proxy server for addresses beginning with,Use semicolon (;)</value>\n  </data>\n  <data name=\"TbSettingsHttpPort\" xml:space=\"preserve\">\n    <value>Http Port</value>\n  </data>\n  <data name=\"TbSettingsIgnoreGeoUpdateCore\" xml:space=\"preserve\">\n    <value>Ignore Geo files when updating core</value>\n  </data>\n  <data name=\"TbSettingsKeepOlderDedupl\" xml:space=\"preserve\">\n    <value>Keep older when deduplication</value>\n  </data>\n  <data name=\"TbSettingsLogEnabled\" xml:space=\"preserve\">\n    <value>Enable Log</value>\n  </data>\n  <data name=\"TbSettingsLogLevel\" xml:space=\"preserve\">\n    <value>Log Level</value>\n  </data>\n  <data name=\"TbSettingsMuxEnabled\" xml:space=\"preserve\">\n    <value>Turn on Mux Multiplexing</value>\n  </data>\n  <data name=\"TbSettingsN\" xml:space=\"preserve\">\n    <value>v2rayN settings</value>\n  </data>\n  <data name=\"TbSettingsPass\" xml:space=\"preserve\">\n    <value>Auth pass</value>\n  </data>\n  <data name=\"TbSettingsRemoteDNS\" xml:space=\"preserve\">\n    <value>Custom DNS (multiple, separated by commas (,))</value>\n  </data>\n  <data name=\"TbSettingsSetUWP\" xml:space=\"preserve\">\n    <value>Set Win10 UWP Loopback</value>\n  </data>\n  <data name=\"TbSettingsSniffingEnabled\" xml:space=\"preserve\">\n    <value>Turn on Sniffing</value>\n  </data>\n  <data name=\"TbSettingsSocksPort\" xml:space=\"preserve\">\n    <value>Socks Port</value>\n  </data>\n  <data name=\"TbSettingsStartBoot\" xml:space=\"preserve\">\n    <value>Start on boot</value>\n  </data>\n  <data name=\"TbSettingsStatistics\" xml:space=\"preserve\">\n    <value>Enable Statistics (Require restart)</value>\n  </data>\n  <data name=\"TbSettingsStatisticsFreshRate\" xml:space=\"preserve\">\n    <value>Statistics freshrate (second)</value>\n  </data>\n  <data name=\"TbSettingsSubConvert\" xml:space=\"preserve\">\n    <value>Subscription conversion Url</value>\n  </data>\n  <data name=\"TbSettingsSystemproxy\" xml:space=\"preserve\">\n    <value>System proxy settings</value>\n  </data>\n  <data name=\"TbSettingsTLS13\" xml:space=\"preserve\">\n    <value>Enable Security Protocol TLS v1.3 (subscription/update)</value>\n  </data>\n  <data name=\"TbSettingsTrayMenuServersLimit\" xml:space=\"preserve\">\n    <value>Tray right-click menu servers display limit</value>\n  </data>\n  <data name=\"TbSettingsUdpEnabled\" xml:space=\"preserve\">\n    <value>Enable UDP</value>\n  </data>\n  <data name=\"TbSettingsUser\" xml:space=\"preserve\">\n    <value>Auth user</value>\n  </data>\n  <data name=\"TbClearSystemProxy\" xml:space=\"preserve\">\n    <value>Clear system proxy</value>\n  </data>\n  <data name=\"TbDisplayGUI\" xml:space=\"preserve\">\n    <value>Display GUI</value>\n  </data>\n  <data name=\"TbGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>GlobalHotkey Settings</value>\n  </data>\n  <data name=\"TbGlobalHotkeySettingTip\" xml:space=\"preserve\">\n    <value>Set directly by pressing the keyboard, Take effect after restart</value>\n  </data>\n  <data name=\"TbNotChangeSystemProxy\" xml:space=\"preserve\">\n    <value>Do not change system proxy</value>\n  </data>\n  <data name=\"TbReset\" xml:space=\"preserve\">\n    <value>Reset</value>\n  </data>\n  <data name=\"TbSetSystemProxy\" xml:space=\"preserve\">\n    <value>Set system proxy</value>\n  </data>\n  <data name=\"TbSystemProxyPac\" xml:space=\"preserve\">\n    <value>Pac Mode</value>\n  </data>\n  <data name=\"menuShareServer\" xml:space=\"preserve\">\n    <value>Share Server (Ctrl+F)</value>\n  </data>\n  <data name=\"menuRouting\" xml:space=\"preserve\">\n    <value>Routing</value>\n  </data>\n  <data name=\"NotRunAsAdmin\" xml:space=\"preserve\">\n    <value>Not Run As Admin</value>\n  </data>\n  <data name=\"RunAsAdmin\" xml:space=\"preserve\">\n    <value>Run As Admin</value>\n  </data>\n  <data name=\"menuMoveBottom\" xml:space=\"preserve\">\n    <value>Move to bottom (B)</value>\n  </data>\n  <data name=\"menuMoveDown\" xml:space=\"preserve\">\n    <value>Down (D)</value>\n  </data>\n  <data name=\"menuMoveTop\" xml:space=\"preserve\">\n    <value>Move to top (T)</value>\n  </data>\n  <data name=\"menuMoveUp\" xml:space=\"preserve\">\n    <value>Up (U)</value>\n  </data>\n  <data name=\"MsgFilterTitle\" xml:space=\"preserve\">\n    <value>Filter, support regular</value>\n  </data>\n  <data name=\"menuWebsiteItem\" xml:space=\"preserve\">\n    <value>{0} Website</value>\n  </data>\n  <data name=\"menuRoutingAdvanced\" xml:space=\"preserve\">\n    <value>Advanced Function</value>\n  </data>\n  <data name=\"menuRoutingAdvancedAdd\" xml:space=\"preserve\">\n    <value>Add</value>\n  </data>\n  <data name=\"menuRoutingAdvancedImportRules\" xml:space=\"preserve\">\n    <value>Import Advanced Rules</value>\n  </data>\n  <data name=\"menuRoutingAdvancedRemove\" xml:space=\"preserve\">\n    <value>Remove selected (Delete)</value>\n  </data>\n  <data name=\"menuRoutingAdvancedSetDefault\" xml:space=\"preserve\">\n    <value>Set as active rule(Enter)</value>\n  </data>\n  <data name=\"menuRoutingBasic\" xml:space=\"preserve\">\n    <value>Basic Function</value>\n  </data>\n  <data name=\"menuRoutingBasicImportRules\" xml:space=\"preserve\">\n    <value>Import Basic Rules</value>\n  </data>\n  <data name=\"TbdomainMatcher\" xml:space=\"preserve\">\n    <value>Domain Matcher</value>\n  </data>\n  <data name=\"TbdomainStrategy\" xml:space=\"preserve\">\n    <value>Domain strategy</value>\n  </data>\n  <data name=\"TbenableRoutingAdvanced\" xml:space=\"preserve\">\n    <value>Enable advanced function</value>\n  </data>\n  <data name=\"TbRoutingTabBlock\" xml:space=\"preserve\">\n    <value>3.Block Domain or IP</value>\n  </data>\n  <data name=\"TbRoutingTabDirect\" xml:space=\"preserve\">\n    <value>2.Direct Domain or IP</value>\n  </data>\n  <data name=\"TbRoutingTabProxy\" xml:space=\"preserve\">\n    <value>1.Proxy Domain or IP</value>\n  </data>\n  <data name=\"TbRoutingTabRuleList\" xml:space=\"preserve\">\n    <value>Pre-defined Rule Set List</value>\n  </data>\n  <data name=\"TbRoutingTips\" xml:space=\"preserve\">\n    <value>*Set the rules, separated by commas (,); The comma in the regular is replaced by &lt;COMMA&gt;</value>\n  </data>\n  <data name=\"menuImportRulesFromClipboard\" xml:space=\"preserve\">\n    <value>Import Rules From Clipboard</value>\n  </data>\n  <data name=\"menuImportRulesFromFile\" xml:space=\"preserve\">\n    <value>Import Rules From File</value>\n  </data>\n  <data name=\"menuImportRulesFromUrl\" xml:space=\"preserve\">\n    <value>Import Rules From Sub Url</value>\n  </data>\n  <data name=\"menuRoutingRuleSetting\" xml:space=\"preserve\">\n    <value>Rule Settings</value>\n  </data>\n  <data name=\"menuRuleAdd\" xml:space=\"preserve\">\n    <value>Rule Add</value>\n  </data>\n  <data name=\"menuRuleExportSelected\" xml:space=\"preserve\">\n    <value>Export Selected Rules</value>\n  </data>\n  <data name=\"menuRuleList\" xml:space=\"preserve\">\n    <value>Rule List</value>\n  </data>\n  <data name=\"menuRuleRemove\" xml:space=\"preserve\">\n    <value>Remove Rules (Delete)</value>\n  </data>\n  <data name=\"menuRoutingRuleDetailsSetting\" xml:space=\"preserve\">\n    <value>RoutingRuleDetailsSetting</value>\n  </data>\n  <data name=\"TbAutoSort\" xml:space=\"preserve\">\n    <value>Domain and ip are auto sorted when saving</value>\n  </data>\n  <data name=\"TbRuleobjectDoc\" xml:space=\"preserve\">\n    <value>Ruleobject Doc</value>\n  </data>\n  <data name=\"TbDnsObjectDoc\" xml:space=\"preserve\">\n    <value>Support DnsObject, Click to view the document</value>\n  </data>\n  <data name=\"SubUrlTips\" xml:space=\"preserve\">\n    <value>Group please leave blank here</value>\n  </data>\n  <data name=\"TipChangeRouting\" xml:space=\"preserve\">\n    <value>Routing setting is changed</value>\n  </data>\n  <data name=\"TipChangeSystemProxy\" xml:space=\"preserve\">\n    <value>System proxy setting is changed</value>\n  </data>\n  <data name=\"TbSettingsRouteOnly\" xml:space=\"preserve\">\n    <value>RouteOnly</value>\n  </data>\n  <data name=\"menuMixedTestServer\" xml:space=\"preserve\">\n    <value>One-click multi test Latency and speed (Ctrl+E)</value>\n  </data>\n  <data name=\"LvTestDelay\" xml:space=\"preserve\">\n    <value>Delay(ms)</value>\n  </data>\n  <data name=\"LvTestSpeed\" xml:space=\"preserve\">\n    <value>Speed(M/s)</value>\n  </data>\n  <data name=\"FailedToRunCore\" xml:space=\"preserve\">\n    <value>Failed to run Core, please see the log</value>\n  </data>\n  <data name=\"LvFilter\" xml:space=\"preserve\">\n    <value>Remarks regular filter</value>\n  </data>\n  <data name=\"TbDisplayLog\" xml:space=\"preserve\">\n    <value>Display Log</value>\n  </data>\n  <data name=\"menuImportOldGuiConfig\" xml:space=\"preserve\">\n    <value>Import old config guiNConfig</value>\n  </data>\n  <data name=\"TbEnableTunAs\" xml:space=\"preserve\">\n    <value>Enable Tun</value>\n  </data>\n  <data name=\"TbSettingsNewPort4LAN\" xml:space=\"preserve\">\n    <value>New Port for LAN</value>\n  </data>\n  <data name=\"TbSettingsTunMode\" xml:space=\"preserve\">\n    <value>TunMode settings</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectIP\" xml:space=\"preserve\">\n    <value>Direct IP CIDR, separated by commas (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectProcess\" xml:space=\"preserve\">\n    <value>Direct Process name, separated by commas (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeShowWindow\" xml:space=\"preserve\">\n    <value>Show console</value>\n  </data>\n  <data name=\"menuMoveToGroup\" xml:space=\"preserve\">\n    <value>Move to group</value>\n  </data>\n  <data name=\"TbSettingsTunModeCustomTemplate\" xml:space=\"preserve\">\n    <value>Custom Template</value>\n  </data>\n  <data name=\"TbSettingsEnableDragDropSort\" xml:space=\"preserve\">\n    <value>Enable Server Drag Drop Sort(Require restart)</value>\n  </data>\n  <data name=\"TbAutoRefresh\" xml:space=\"preserve\">\n    <value>AutoRefresh</value>\n  </data>\n  <data name=\"SpeedtestingSkip\" xml:space=\"preserve\">\n    <value>Skip test</value>\n  </data>\n  <data name=\"menuEditServer\" xml:space=\"preserve\">\n    <value>Edit Server (Ctrl+D)</value>\n  </data>\n  <data name=\"TbSettingsDoubleClick2Activate\" xml:space=\"preserve\">\n    <value>Double-click server make active</value>\n  </data>\n  <data name=\"SpeedtestingCompleted\" xml:space=\"preserve\">\n    <value>Test completed</value>\n  </data>\n  <data name=\"TbSettingsDefFingerprint\" xml:space=\"preserve\">\n    <value>Default TLS fingerprint</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgent\" xml:space=\"preserve\">\n    <value>User-Agent</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgentTips\" xml:space=\"preserve\">\n    <value>This parameter is valid only for tcp/http and ws</value>\n  </data>\n  <data name=\"TbSettingsCurrentFontFamily\" xml:space=\"preserve\">\n    <value>FontFamily(Require restart)</value>\n  </data>\n  <data name=\"TbSettingsCurrentFontFamilyTip\" xml:space=\"preserve\">\n    <value>Copy the font TTF file to the directory guiFonts, restart the settings</value>\n  </data>\n  <data name=\"TbSettingsSocksPortTip\" xml:space=\"preserve\">\n    <value>http port=socks port+1</value>\n  </data>\n  <data name=\"TbSettingsStartBootTip\" xml:space=\"preserve\">\n    <value>Set this with admin privileges, get admin privileges after startup</value>\n  </data>\n  <data name=\"TbSettingsFontSize\" xml:space=\"preserve\">\n    <value>FontSize</value>\n  </data>\n  <data name=\"TbSettingsTunModeProxyIP\" xml:space=\"preserve\">\n    <value>Proxy IP CIDR, separated by commas (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeProxyProcess\" xml:space=\"preserve\">\n    <value>Proxy Process name, separated by commas (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeBypassMode\" xml:space=\"preserve\">\n    <value>Bypass Mode</value>\n  </data>\n  <data name=\"TbSettingsTunModeBypassModeTip\" xml:space=\"preserve\">\n    <value>Enable: If no route matches, the final proxy</value>\n  </data>\n  <data name=\"TbSettingsSpeedTestTimeout\" xml:space=\"preserve\">\n    <value>SpeedTest Single Timeout Value</value>\n  </data>\n  <data name=\"TbSettingsSpeedTestUrl\" xml:space=\"preserve\">\n    <value>SpeedTest Url</value>\n  </data>\n  <data name=\"TbSettingsTunModeDNS\" xml:space=\"preserve\">\n    <value>DNS object, e.g. {\"servers\":[]}</value>\n  </data>\n  <data name=\"menuMoveTo\" xml:space=\"preserve\">\n    <value>Move up and down</value>\n  </data>\n  <data name=\"TbPublicKey\" xml:space=\"preserve\">\n    <value>PublicKey</value>\n  </data>\n  <data name=\"TbShortId\" xml:space=\"preserve\">\n    <value>ShortId</value>\n  </data>\n  <data name=\"TbSpiderX\" xml:space=\"preserve\">\n    <value>SpiderX</value>\n  </data>\n  <data name=\"TbSettingsEnableHWA\" xml:space=\"preserve\">\n    <value>Enable hardware acceleration(Require restart)</value>\n  </data>\n  <data name=\"SpeedtestingWait\" xml:space=\"preserve\">\n    <value>Waiting for testing</value>\n  </data>\n  <data name=\"TipDisplayLog\" xml:space=\"preserve\">\n    <value>Please turn off when there is an abnormal disconnection</value>\n  </data>\n  <data name=\"MsgSkipSubscriptionUpdate\" xml:space=\"preserve\">\n    <value>Updates are not enabled, skip this subscription</value>\n  </data>\n  <data name=\"menuRebootAsAdmin\" xml:space=\"preserve\">\n    <value>Reboot as administrator</value>\n  </data>\n  <data name=\"LvMoreUrl\" xml:space=\"preserve\">\n    <value>More urls, separated by commas;Subscription conversion will be invalid</value>\n  </data>\n  <data name=\"SpeedDisplayText\" xml:space=\"preserve\">\n    <value>{0}:{1}/s↑ | {2}/s↓</value>\n  </data>\n  <data name=\"LvAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Automatic update interval(minutes)</value>\n  </data>\n  <data name=\"TbSettingsLogEnabledToFile\" xml:space=\"preserve\">\n    <value>Enable logging to file</value>\n  </data>\n  <data name=\"LvConvertTarget\" xml:space=\"preserve\">\n    <value>Convert target type</value>\n  </data>\n  <data name=\"LvConvertTargetTip\" xml:space=\"preserve\">\n    <value>Please leave blank if no conversion is required</value>\n  </data>\n  <data name=\"menuDNSSetting\" xml:space=\"preserve\">\n    <value>DNS Settings</value>\n  </data>\n  <data name=\"TbSettingsCoreDnsSingbox\" xml:space=\"preserve\">\n    <value>Sing-box DNS settings</value>\n  </data>\n  <data name=\"TbDnsSingboxObjectDoc\" xml:space=\"preserve\">\n    <value>Please fill in DNS Structure, Click to view the document</value>\n  </data>\n  <data name=\"TBSettingDnsImportDefConfig\" xml:space=\"preserve\">\n    <value>Click to import default DNS config</value>\n  </data>\n  <data name=\"TbdomainStrategy4Singbox\" xml:space=\"preserve\">\n    <value>Sing-box domain strategy</value>\n  </data>\n  <data name=\"TbEnableProxy\" xml:space=\"preserve\">\n    <value>Use Proxy</value>\n  </data>\n  <data name=\"RoutingAllSites\" xml:space=\"preserve\">\n    <value>All Sites</value>\n  </data>\n  <data name=\"RoutingBlockedSites\" xml:space=\"preserve\">\n    <value>Blocked Sites</value>\n  </data>\n  <data name=\"RoutingForeignSites\" xml:space=\"preserve\">\n    <value>Foreign Sites</value>\n  </data>\n</root>"
  },
  {
    "path": "v2rayN/v2rayN/Resx/ResUI.ru.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=\"BatchExportSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>Экспортирование подписок в буфер обмена успешно завершено</value>\n  </data>\n  <data name=\"BatchExportURLSuccessfully\" xml:space=\"preserve\">\n    <value>Экспортирование URL в буфер обмена успешно завершено</value>\n  </data>\n  <data name=\"CheckServerSettings\" xml:space=\"preserve\">\n    <value>Пожалуйста, сначала проверьте настройки сервера</value>\n  </data>\n  <data name=\"ConfigurationFormatIncorrect\" xml:space=\"preserve\">\n    <value>Недопустимый формат конфигурации</value>\n  </data>\n  <data name=\"CustomServerTips\" xml:space=\"preserve\">\n    <value>Обратите внимание, что пользовательская конфигурация полностью зависит от вашей собственной конфигурации и работает не со всеми настройками. Если вы хотите использовать системный прокси, пожалуйста, измените порт прослушивания вручную.</value>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>Загрузка...</value>\n  </data>\n  <data name=\"downloadSpeed\" xml:space=\"preserve\">\n    <value>Скорость загрузки</value>\n  </data>\n  <data name=\"DownloadYesNo\" xml:space=\"preserve\">\n    <value>Хотите загрузить? {0}</value>\n  </data>\n  <data name=\"FailedConversionConfiguration\" xml:space=\"preserve\">\n    <value>Не удалось преобразовать файл конфигурации</value>\n  </data>\n  <data name=\"FailedGenDefaultConfiguration\" xml:space=\"preserve\">\n    <value>Не удалось создать файл конфигурации по умолчаниюe</value>\n  </data>\n  <data name=\"FailedGetDefaultConfiguration\" xml:space=\"preserve\">\n    <value>Не удалось получить конфигурацию по умолчанию</value>\n  </data>\n  <data name=\"FailedImportedCustomServer\" xml:space=\"preserve\">\n    <value>Не удалось импортировать сервер пользовательской конфигурации</value>\n  </data>\n  <data name=\"FailedReadConfiguration\" xml:space=\"preserve\">\n    <value>Не удалось прочитать файл конфигурации</value>\n  </data>\n  <data name=\"FillCorrectServerPort\" xml:space=\"preserve\">\n    <value>Пожалуйста, укажите порт сервера в правильном формате</value>\n  </data>\n  <data name=\"FillKcpParameters\" xml:space=\"preserve\">\n    <value>Пожалуйста, заполните параметры KCP корректно</value>\n  </data>\n  <data name=\"FillLocalListeningPort\" xml:space=\"preserve\">\n    <value>Пожалуйста, укажите локальный порт прослушивания</value>\n  </data>\n  <data name=\"FillPassword\" xml:space=\"preserve\">\n    <value>Пожалуйста, введите пароль</value>\n  </data>\n  <data name=\"FillServerAddress\" xml:space=\"preserve\">\n    <value>Пожалуйста, заполните адрес сервера</value>\n  </data>\n  <data name=\"FillUUID\" xml:space=\"preserve\">\n    <value>Пожалуйста, заполните идентификатор пользователя</value>\n  </data>\n  <data name=\"IncorrectClientConfiguration\" xml:space=\"preserve\">\n    <value>Некорректный файл конфигурации клиента, пожалуйста, проверьте</value>\n  </data>\n  <data name=\"Incorrectconfiguration\" xml:space=\"preserve\">\n    <value>Некорректная конфигурация, пожалуйста, проверьте</value>\n  </data>\n  <data name=\"IncorrectServerConfiguration\" xml:space=\"preserve\">\n    <value>Некорректный файл конфигурации сервера, пожалуйста, проверьте</value>\n  </data>\n  <data name=\"InitialConfiguration\" xml:space=\"preserve\">\n    <value>Исходная конфигурация</value>\n  </data>\n  <data name=\"IsLatestCore\" xml:space=\"preserve\">\n    <value>{0} является последней версией.</value>\n  </data>\n  <data name=\"IsLatestN\" xml:space=\"preserve\">\n    <value>{0} является последней версией.</value>\n  </data>\n  <data name=\"LvAddress\" xml:space=\"preserve\">\n    <value>Адрес</value>\n  </data>\n  <data name=\"LvEncryptionMethod\" xml:space=\"preserve\">\n    <value>Безопасность</value>\n  </data>\n  <data name=\"LvPort\" xml:space=\"preserve\">\n    <value>Порт</value>\n  </data>\n  <data name=\"LvServiceType\" xml:space=\"preserve\">\n    <value>Тип</value>\n  </data>\n  <data name=\"LvSubscription\" xml:space=\"preserve\">\n    <value>Группа подписки</value>\n  </data>\n  <data name=\"LvTodayDownloadDataAmount\" xml:space=\"preserve\">\n    <value>Загружено трафика сегодня</value>\n  </data>\n  <data name=\"LvTodayUploadDataAmount\" xml:space=\"preserve\">\n    <value>Отдано трафика сегодня</value>\n  </data>\n  <data name=\"LvTotalDownloadDataAmount\" xml:space=\"preserve\">\n    <value>Всего загружено</value>\n  </data>\n  <data name=\"LvTotalUploadDataAmount\" xml:space=\"preserve\">\n    <value>Всего отдано</value>\n  </data>\n  <data name=\"LvTransportProtocol\" xml:space=\"preserve\">\n    <value>Протокол</value>\n  </data>\n  <data name=\"MsgClearSubscription\" xml:space=\"preserve\">\n    <value>Очистить контент оригинальной подписки</value>\n  </data>\n  <data name=\"MsgDownloadV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>Ядро успешно загружено</value>\n  </data>\n  <data name=\"MsgFailedImportSubscription\" xml:space=\"preserve\">\n    <value>Не удалось импортировать содержимое подписки</value>\n  </data>\n  <data name=\"MsgGetSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>Содержимое подписки успешно импортировано</value>\n  </data>\n  <data name=\"MsgNoValidSubscription\" xml:space=\"preserve\">\n    <value>Нет установлены подписки</value>\n  </data>\n  <data name=\"MsgParsingSuccessfully\" xml:space=\"preserve\">\n    <value>Парсинг {0} прошел успешно</value>\n  </data>\n  <data name=\"MsgStartGettingSubscriptions\" xml:space=\"preserve\">\n    <value>Начинаю получать подписки</value>\n  </data>\n  <data name=\"MsgStartUpdating\" xml:space=\"preserve\">\n    <value>Начинаю обновление {0}...</value>\n  </data>\n  <data name=\"MsgSubscriptionDecodingFailed\" xml:space=\"preserve\">\n    <value>Некорректное содержимое подписки</value>\n  </data>\n  <data name=\"MsgUnpacking\" xml:space=\"preserve\">\n    <value>распаковывается...</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionEnd\" xml:space=\"preserve\">\n    <value>Обновление подписки закончено</value>\n  </data>\n  <data name=\"MsgNothingUpdated\" xml:space=\"preserve\">\n    <value>ничего не было обновлено</value>\n  </data>\n  <data name=\"MsgStartProgramAsAdmin\" xml:space=\"preserve\">\n    <value>Для этого программа должна быть запущена в режиме Administrator</value>\n  </data>\n  <data name=\"MsgNothingUpdated\" xml:space=\"preserve\">\n    <value>Недопустимая ссылка</value>\n  </data>\n  <data name=\"MsgProgramNeedsRestarting\" xml:space=\"preserve\">\n    <value>Для выполнения этой операции программу необходимо перезапустить !</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionStart\" xml:space=\"preserve\">\n    <value>Обновление подписки начинается</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>Успешное обновление ядра</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfullyMore\" xml:space=\"preserve\">\n    <value>Успешное обновление ядра! Перезапуск службы...</value>\n  </data>\n  <data name=\"NonvmessOrssProtocol\" xml:space=\"preserve\">\n    <value>Не является протоколом Vmess или SS</value>\n  </data>\n  <data name=\"NonVmessService\" xml:space=\"preserve\">\n    <value> нестандартный сервис, эта функция недействительна</value>\n  </data>\n  <data name=\"NotFoundCore\" xml:space=\"preserve\">\n    <value>Файл Core (имя файла: {1}) не найден в папке ({0}), загрузите и поместите его в папку, адрес загрузки: {2}</value>\n  </data>\n  <data name=\"NoValidQRcodeFound\" xml:space=\"preserve\">\n    <value>Сканирование завершено, не найден корректный QR код</value>\n  </data>\n  <data name=\"OperationFailed\" xml:space=\"preserve\">\n    <value> операция безуспешна, проверьте и попробуйте ещё раз</value>\n  </data>\n  <data name=\"PleaseFillRemarks\" xml:space=\"preserve\">\n    <value>Пожалуйста, заполните примечания</value>\n  </data>\n  <data name=\"PleaseSelectEncryption\" xml:space=\"preserve\">\n    <value>Пожалуйста, выберите метод шифрования</value>\n  </data>\n  <data name=\"PleaseSelectProtocol\" xml:space=\"preserve\">\n    <value>Пожалуйста, выберите протокол</value>\n  </data>\n  <data name=\"PleaseSelectServer\" xml:space=\"preserve\">\n    <value>Сначала выберите сервер</value>\n  </data>\n  <data name=\"RemoveDuplicateServerResult\" xml:space=\"preserve\">\n    <value>Удаление дублей завершено. Старая: {0}, Новая: {1}.</value>\n  </data>\n  <data name=\"RemoveServer\" xml:space=\"preserve\">\n    <value>Вы уверены, что хотите удалить сервер?</value>\n  </data>\n  <data name=\"SaveClientConfigurationIn\" xml:space=\"preserve\">\n    <value>Файл конфигурации клиента сохранен по адресу: {0}</value>\n  </data>\n  <data name=\"StartService\" xml:space=\"preserve\">\n    <value>Запуск сервиса ({0})...</value>\n  </data>\n  <data name=\"SuccessfulConfiguration\" xml:space=\"preserve\">\n    <value>Конфигурация успешна\n{0}</value>\n  </data>\n  <data name=\"SuccessfullyImportedCustomServer\" xml:space=\"preserve\">\n    <value>Пользовательский сервер конфигурации успешно импортирован.</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaClipboard\" xml:space=\"preserve\">\n    <value>{0} серверов импортировано из буфера обмена.</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaScan\" xml:space=\"preserve\">\n    <value>Сканирование URL-адреса импорта успешна.</value>\n  </data>\n  <data name=\"TestMeOutput\" xml:space=\"preserve\">\n    <value>Пинг текущей службы: {0} мс</value>\n  </data>\n  <data name=\"OperationSuccess\" xml:space=\"preserve\">\n    <value>Операция успешна</value>\n  </data>\n  <data name=\"PleaseSelectRules\" xml:space=\"preserve\">\n    <value>Выберите правила</value>\n  </data>\n  <data name=\"RemoveRules\" xml:space=\"preserve\">\n    <value>Вы уверены, что хотите удалить правила?</value>\n  </data>\n  <data name=\"RoutingRuleDetailRequiredTips\" xml:space=\"preserve\">\n    <value>{0}, Один из обязательных..</value>\n  </data>\n  <data name=\"LvRemarks\" xml:space=\"preserve\">\n    <value>Примечания</value>\n  </data>\n  <data name=\"LvUrl\" xml:space=\"preserve\">\n    <value>Url(Необязательно)</value>\n  </data>\n  <data name=\"LvCount\" xml:space=\"preserve\">\n    <value>Количество</value>\n  </data>\n  <data name=\"MsgNeedUrl\" xml:space=\"preserve\">\n    <value>Пожалуйста, заполните адрес (Url)</value>\n  </data>\n  <data name=\"AddBatchRoutingRulesYesNo\" xml:space=\"preserve\">\n    <value>Вы хотите добавить правила? Выберите «Да», чтобы добавить, выберите иное, чтобы заменить</value>\n  </data>\n  <data name=\"MsgDownloadGeoFileSuccessfully\" xml:space=\"preserve\">\n    <value>Загрузка GeoFile: {0} успешна</value>\n  </data>\n  <data name=\"MsgInformationTitle\" xml:space=\"preserve\">\n    <value>Информация</value>\n  </data>\n  <data name=\"LvCustomIcon\" xml:space=\"preserve\">\n    <value>Пользовательская иконка</value>\n  </data>\n  <data name=\"FillCorrectDNSText\" xml:space=\"preserve\">\n    <value>Пожалуйста, заполните правильный пользовательский DNS</value>\n  </data>\n  <data name=\"TransportPathTip1\" xml:space=\"preserve\">\n    <value>*ws путь</value>\n  </data>\n  <data name=\"TransportPathTip2\" xml:space=\"preserve\">\n    <value>*h2 путь</value>\n  </data>\n  <data name=\"TransportPathTip3\" xml:space=\"preserve\">\n    <value>*QUIC ключ/Kcp seed</value>\n  </data>\n  <data name=\"TransportPathTip4\" xml:space=\"preserve\">\n    <value>*grpc serviceName</value>\n  </data>\n  <data name=\"TransportRequestHostTip1\" xml:space=\"preserve\">\n    <value>*http хосты разделенные запятыми (,)</value>\n  </data>\n  <data name=\"TransportRequestHostTip2\" xml:space=\"preserve\">\n    <value>*ws хост</value>\n  </data>\n  <data name=\"TransportRequestHostTip3\" xml:space=\"preserve\">\n    <value>*h2 хосты разделенные запятыми (,)</value>\n  </data>\n  <data name=\"TransportRequestHostTip4\" xml:space=\"preserve\">\n    <value>* безопасность QUIC</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip1\" xml:space=\"preserve\">\n    <value>* тип TCP камуфляжа</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip2\" xml:space=\"preserve\">\n    <value>* тип KCP камуфляжа</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip3\" xml:space=\"preserve\">\n    <value>* тип QUIC камуфляжа</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip4\" xml:space=\"preserve\">\n    <value>* режим grpc</value>\n  </data>\n  <data name=\"LvTLS\" xml:space=\"preserve\">\n    <value>TLS</value>\n  </data>\n  <data name=\"TransportPathTip5\" xml:space=\"preserve\">\n    <value>*Kcp seed</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeyFailed\" xml:space=\"preserve\">\n    <value>Не удалось зарегистрировать глобальную горячую клавишу {0}, причина: {1}</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeySuccessfully\" xml:space=\"preserve\">\n    <value>Глобальная горячая клавиша {0} зарегистрирована успешно</value>\n  </data>\n  <data name=\"UngroupedServers\" xml:space=\"preserve\">\n    <value>Разгруппировано</value>\n  </data>\n  <data name=\"AllGroupServers\" xml:space=\"preserve\">\n    <value>Все сервера</value>\n  </data>\n  <data name=\"FillServerAddressCustom\" xml:space=\"preserve\">\n    <value>Пожалуйста, просмотрите, чтобы импортировать конфигурацию сервера</value>\n  </data>\n  <data name=\"SystemProxy\" xml:space=\"preserve\">\n    <value>Системный прокси</value>\n  </data>\n  <data name=\"Speedtesting\" xml:space=\"preserve\">\n    <value>Тестирование...</value>\n  </data>\n  <data name=\"TooManyServersTip\" xml:space=\"preserve\">\n    <value>Слишком много серверов, пожалуйста, откройте главный интерфейс</value>\n  </data>\n  <data name=\"LabLAN\" xml:space=\"preserve\">\n    <value>LAN</value>\n  </data>\n  <data name=\"LabLocal\" xml:space=\"preserve\">\n    <value>Локальный</value>\n  </data>\n  <data name=\"MsgServerTitle\" xml:space=\"preserve\">\n    <value>Фильтр серверов</value>\n  </data>\n  <data name=\"menuCheckUpdate\" xml:space=\"preserve\">\n    <value>Проверить обновления</value>\n  </data>\n  <data name=\"menuClose\" xml:space=\"preserve\">\n    <value>Закрыть</value>\n  </data>\n  <data name=\"menuExit\" xml:space=\"preserve\">\n    <value>Выход</value>\n  </data>\n  <data name=\"menuGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>Глобальная настройка горячих клавиш</value>\n  </data>\n  <data name=\"menuHelp\" xml:space=\"preserve\">\n    <value>Помощь</value>\n  </data>\n  <data name=\"menuOptionSetting\" xml:space=\"preserve\">\n    <value>Настройка параметров</value>\n  </data>\n  <data name=\"menuPromotion\" xml:space=\"preserve\">\n    <value>Содействие</value>\n  </data>\n  <data name=\"menuReload\" xml:space=\"preserve\">\n    <value>Перезагрузка</value>\n  </data>\n  <data name=\"menuRoutingSetting\" xml:space=\"preserve\">\n    <value>Настройки маршрутизации</value>\n  </data>\n  <data name=\"menuServers\" xml:space=\"preserve\">\n    <value>Сервера</value>\n  </data>\n  <data name=\"menuSetting\" xml:space=\"preserve\">\n    <value>Настройки</value>\n  </data>\n  <data name=\"menuSubGroupUpdate\" xml:space=\"preserve\">\n    <value>Обновить текущую подписку без прокси</value>\n  </data>\n  <data name=\"menuSubGroupUpdateViaProxy\" xml:space=\"preserve\">\n    <value>Обновить текущую подписку с прокси</value>\n  </data>\n  <data name=\"menuSubscription\" xml:space=\"preserve\">\n    <value>Группа подписки</value>\n  </data>\n  <data name=\"menuSubSetting\" xml:space=\"preserve\">\n    <value>Настройки группы подписки</value>\n  </data>\n  <data name=\"menuSubUpdate\" xml:space=\"preserve\">\n    <value>Обновить подписку без прокси</value>\n  </data>\n  <data name=\"menuSubUpdateViaProxy\" xml:space=\"preserve\">\n    <value>Обновить подписку с прокси</value>\n  </data>\n  <data name=\"menuSystemproxy\" xml:space=\"preserve\">\n    <value>Системный прокси</value>\n  </data>\n  <data name=\"menuSystemProxyClear\" xml:space=\"preserve\">\n    <value>Очистить системный прокси</value>\n  </data>\n  <data name=\"menuSystemProxyNothing\" xml:space=\"preserve\">\n    <value>Не менять системный прокси</value>\n  </data>\n  <data name=\"menuSystemProxyPac\" xml:space=\"preserve\">\n    <value>Режим PAC</value>\n  </data>\n  <data name=\"menuSystemProxySet\" xml:space=\"preserve\">\n    <value>Установить системный прокси</value>\n  </data>\n  <data name=\"TbSettingsColor\" xml:space=\"preserve\">\n    <value>Цвет</value>\n  </data>\n  <data name=\"TbSettingsColorMode\" xml:space=\"preserve\">\n    <value>Тёмный режим</value>\n  </data>\n  <data name=\"TbSettingsLanguage\" xml:space=\"preserve\">\n    <value>Язык (требуется перезапуск)</value>\n  </data>\n  <data name=\"menuAddServerViaClipboard\" xml:space=\"preserve\">\n    <value>Импорт массива URL из буфера обмена (Ctrl+V)</value>\n  </data>\n  <data name=\"menuAddServerViaScan\" xml:space=\"preserve\">\n    <value>Сканировать QR-код с экрана (Ctrl+S)</value>\n  </data>\n  <data name=\"menuCopyServer\" xml:space=\"preserve\">\n    <value>Клонировать выбранный сервер</value>\n  </data>\n  <data name=\"menuRemoveDuplicateServer\" xml:space=\"preserve\">\n    <value>Удалить дубликаты серверов</value>\n  </data>\n  <data name=\"menuRemoveServer\" xml:space=\"preserve\">\n    <value>Удалить выбранные серверы (Delete)</value>\n  </data>\n  <data name=\"menuSetDefaultServer\" xml:space=\"preserve\">\n    <value>Установить как активный сервер (Enter)</value>\n  </data>\n  <data name=\"menuClearServerStatistics\" xml:space=\"preserve\">\n    <value>Очистить всю статистику</value>\n  </data>\n  <data name=\"menuPingServer\" xml:space=\"preserve\">\n    <value>Проверить пинг серверов (Ctrl+P)</value>\n  </data>\n  <data name=\"menuRealPingServer\" xml:space=\"preserve\">\n    <value>Тест на реальную задержку серверов (Ctrl+R)</value>\n  </data>\n  <data name=\"menuSortServerResult\" xml:space=\"preserve\">\n    <value>Сортировать по результату теста</value>\n  </data>\n  <data name=\"menuSpeedServer\" xml:space=\"preserve\">\n    <value>Проверить скорость загрузки серверов (Ctrl+T)</value>\n  </data>\n  <data name=\"menuTcpingServer\" xml:space=\"preserve\">\n    <value>Тестировать сервера с tcping (Ctrl+O)</value>\n  </data>\n  <data name=\"menuTestMe\" xml:space=\"preserve\">\n    <value>Проверить текущий статус службы</value>\n  </data>\n  <data name=\"menuExport2ClientConfig\" xml:space=\"preserve\">\n    <value>Экспортировать выбранный сервер для клиента</value>\n  </data>\n  <data name=\"menuExport2ShareUrl\" xml:space=\"preserve\">\n    <value>Экспорт URL-адресов общего доступа в буфер обмена (Ctrl+C)</value>\n  </data>\n  <data name=\"menuExport2SubContent\" xml:space=\"preserve\">\n    <value>Экспортировать ссылку-подписку (base64) в буфер обмена</value>\n  </data>\n  <data name=\"menuAddCustomServer\" xml:space=\"preserve\">\n    <value>Добавить сервер пользовательской конфигурации</value>\n  </data>\n  <data name=\"menuAddShadowsocksServer\" xml:space=\"preserve\">\n    <value>Добавить сервер [Shadowsocks]</value>\n  </data>\n  <data name=\"menuAddSocksServer\" xml:space=\"preserve\">\n    <value>Добавить сервер [Socks]</value>\n  </data>\n  <data name=\"menuAddTrojanServer\" xml:space=\"preserve\">\n    <value>Добавить сервер [Trojan]</value>\n  </data>\n  <data name=\"menuAddVlessServer\" xml:space=\"preserve\">\n    <value>Добавить сервер [VLESS]</value>\n  </data>\n  <data name=\"menuAddVmessServer\" xml:space=\"preserve\">\n    <value>Добавить сервер [VMess]</value>\n  </data>\n  <data name=\"menuSelectAll\" xml:space=\"preserve\">\n    <value>Выбрать все (Ctrl+A)</value>\n  </data>\n  <data name=\"menuMsgViewClear\" xml:space=\"preserve\">\n    <value>Очистить все</value>\n  </data>\n  <data name=\"menuMsgViewCopy\" xml:space=\"preserve\">\n    <value>Скопировать (Ctrl+C)</value>\n  </data>\n  <data name=\"menuMsgViewCopyAll\" xml:space=\"preserve\">\n    <value>Скопировать все</value>\n  </data>\n  <data name=\"menuMsgViewFilter\" xml:space=\"preserve\">\n    <value>Установить фильтры сообщений</value>\n  </data>\n  <data name=\"menuMsgViewSelectAll\" xml:space=\"preserve\">\n    <value>Выбрать все (Ctrl+A)</value>\n  </data>\n  <data name=\"menuSubAdd\" xml:space=\"preserve\">\n    <value>Добавить</value>\n  </data>\n  <data name=\"menuSubDelete\" xml:space=\"preserve\">\n    <value>Удалить</value>\n  </data>\n  <data name=\"menuSubEdit\" xml:space=\"preserve\">\n    <value>Редактировать</value>\n  </data>\n  <data name=\"menuSubShare\" xml:space=\"preserve\">\n    <value>Поделиться</value>\n  </data>\n  <data name=\"LvEnabled\" xml:space=\"preserve\">\n    <value>Включены обновления</value>\n  </data>\n  <data name=\"LvSort\" xml:space=\"preserve\">\n    <value>Сортировка</value>\n  </data>\n  <data name=\"LvUserAgent\" xml:space=\"preserve\">\n    <value>User Agent</value>\n  </data>\n  <data name=\"TbCancel\" xml:space=\"preserve\">\n    <value>Отмена</value>\n  </data>\n  <data name=\"TbConfirm\" xml:space=\"preserve\">\n    <value>Подтвердить</value>\n  </data>\n  <data name=\"GbTransport\" xml:space=\"preserve\">\n    <value>Транспорт</value>\n  </data>\n  <data name=\"TbAddress\" xml:space=\"preserve\">\n    <value>Адрес</value>\n  </data>\n  <data name=\"TbAllowInsecure\" xml:space=\"preserve\">\n    <value>Разрешить небезопасные</value>\n  </data>\n  <data name=\"TbAlpn\" xml:space=\"preserve\">\n    <value>ALPN</value>\n  </data>\n  <data name=\"TbAlterId\" xml:space=\"preserve\">\n    <value>AlterId</value>\n  </data>\n  <data name=\"TbFingerprint\" xml:space=\"preserve\">\n    <value>Отпечаток</value>\n  </data>\n  <data name=\"TbHeaderType\" xml:space=\"preserve\">\n    <value>Тип камуфляжа</value>\n  </data>\n  <data name=\"TbId\" xml:space=\"preserve\">\n    <value>UUID(id)</value>\n  </data>\n  <data name=\"TbNetwork\" xml:space=\"preserve\">\n    <value>Транспортный протокол сети</value>\n  </data>\n  <data name=\"TbPath\" xml:space=\"preserve\">\n    <value>Путь</value>\n  </data>\n  <data name=\"TbPort\" xml:space=\"preserve\">\n    <value>Порт</value>\n  </data>\n  <data name=\"TbRemarks\" xml:space=\"preserve\">\n    <value>Псевдоним (примечания)</value>\n  </data>\n  <data name=\"TbRequestHost\" xml:space=\"preserve\">\n    <value>Маскирующий домен (хост)</value>\n  </data>\n  <data name=\"TbSecurity\" xml:space=\"preserve\">\n    <value>Метод шифрования</value>\n  </data>\n  <data name=\"TbSNI\" xml:space=\"preserve\">\n    <value>SNI</value>\n  </data>\n  <data name=\"TbStreamSecurity\" xml:space=\"preserve\">\n    <value>TLS</value>\n  </data>\n  <data name=\"TipNetwork\" xml:space=\"preserve\">\n    <value>* По-умолчанию TCP</value>\n  </data>\n  <data name=\"TbCoreType\" xml:space=\"preserve\">\n    <value>Ядро</value>\n  </data>\n  <data name=\"TbFlow5\" xml:space=\"preserve\">\n    <value>Поток</value>\n  </data>\n  <data name=\"TbGUID\" xml:space=\"preserve\">\n    <value>Генерировать</value>\n  </data>\n  <data name=\"TbId3\" xml:space=\"preserve\">\n    <value>Пароль</value>\n  </data>\n  <data name=\"TbId4\" xml:space=\"preserve\">\n    <value>Пароль(Необязательно)</value>\n  </data>\n  <data name=\"TbId5\" xml:space=\"preserve\">\n    <value>UUID(id)</value>\n  </data>\n  <data name=\"TbSecurity3\" xml:space=\"preserve\">\n    <value>Шифрование</value>\n  </data>\n  <data name=\"TbSecurity4\" xml:space=\"preserve\">\n    <value>Пользователь(Необязательно)</value>\n  </data>\n  <data name=\"TbSecurity5\" xml:space=\"preserve\">\n    <value>Шифрования</value>\n  </data>\n  <data name=\"TbPreSocksPort\" xml:space=\"preserve\">\n    <value>txtPreSocksPort</value>\n  </data>\n  <data name=\"TipPreSocksPort\" xml:space=\"preserve\">\n    <value>* После установки этого значения служба socks будет запущена с использованием Sing-box для обеспечения таких функций, как отображение скорости</value>\n  </data>\n  <data name=\"TbBrowse\" xml:space=\"preserve\">\n    <value>Просмотр</value>\n  </data>\n  <data name=\"TbEdit\" xml:space=\"preserve\">\n    <value>Редактировать</value>\n  </data>\n  <data name=\"TbSettingsAdvancedProtocol\" xml:space=\"preserve\">\n    <value>Расширенные настройки прокси, выбор протокола (необязательно)</value>\n  </data>\n  <data name=\"TbSettingsAllowLAN\" xml:space=\"preserve\">\n    <value>Разрешить подключения из локальной сети</value>\n  </data>\n  <data name=\"TbSettingsAutoHideStartup\" xml:space=\"preserve\">\n    <value>Auto hide startup</value>\n  </data>\n  <data name=\"TbSettingsAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>Интервал автоматического обновления Geo в часах</value>\n  </data>\n  <data name=\"TbSettingsCore\" xml:space=\"preserve\">\n    <value>Ядро: базовые настройки</value>\n  </data>\n  <data name=\"TbSettingsCoreDns\" xml:space=\"preserve\">\n    <value>V2ray DNS settings</value>\n  </data>\n  <data name=\"TbSettingsCoreKcp\" xml:space=\"preserve\">\n    <value>Ядро: настройки KCP</value>\n  </data>\n  <data name=\"TbSettingsCoreType\" xml:space=\"preserve\">\n    <value>Настройки типа ядра</value>\n  </data>\n  <data name=\"TbSettingsDefAllowInsecure\" xml:space=\"preserve\">\n    <value>Разрешить небезопасные</value>\n  </data>\n  <data name=\"TbSettingsDomainStrategy4Freedom\" xml:space=\"preserve\">\n    <value>Outbound Freedom domainStrategy</value>\n  </data>\n  <data name=\"TbSettingsEnableAutoAdjustMainLvColWidth\" xml:space=\"preserve\">\n    <value>Автоматически регулировать ширину столбца после обновления подписки</value>\n  </data>\n  <data name=\"TbSettingsEnableCheckPreReleaseUpdate\" xml:space=\"preserve\">\n    <value>Проверить наличие предварительных обновлений</value>\n  </data>\n  <data name=\"TbSettingsException\" xml:space=\"preserve\">\n    <value>Исключение</value>\n  </data>\n  <data name=\"TbSettingsExceptionTip\" xml:space=\"preserve\">\n    <value>Исключение. Не используйте прокси-сервер для адресов, начинающихся с (,), используйте точку с запятой (;)</value>\n  </data>\n  <data name=\"TbSettingsHttpPort\" xml:space=\"preserve\">\n    <value>HTTP порт</value>\n  </data>\n  <data name=\"TbSettingsIgnoreGeoUpdateCore\" xml:space=\"preserve\">\n    <value>Игнорировать файлы Geo при обновлении ядра</value>\n  </data>\n  <data name=\"TbSettingsKeepOlderDedupl\" xml:space=\"preserve\">\n    <value>Сохранить старые при удалении дублей</value>\n  </data>\n  <data name=\"TbSettingsLogEnabled\" xml:space=\"preserve\">\n    <value>Записывать логи</value>\n  </data>\n  <data name=\"TbSettingsLogLevel\" xml:space=\"preserve\">\n    <value>Уровень логгирования</value>\n  </data>\n  <data name=\"TbSettingsMuxEnabled\" xml:space=\"preserve\">\n    <value>Включите мультиплексирование Mux</value>\n  </data>\n  <data name=\"TbSettingsN\" xml:space=\"preserve\">\n    <value>Настройки v2rayN</value>\n  </data>\n  <data name=\"TbSettingsPass\" xml:space=\"preserve\">\n    <value>Пароль аутентификации</value>\n  </data>\n  <data name=\"TbSettingsRemoteDNS\" xml:space=\"preserve\">\n    <value>Пользовательский DNS (если несколько делите с запятыми (,))</value>\n  </data>\n  <data name=\"TbSettingsSetUWP\" xml:space=\"preserve\">\n    <value>Set Win10 UWP Loopback</value>\n  </data>\n  <data name=\"TbSettingsSniffingEnabled\" xml:space=\"preserve\">\n    <value>Включить сниффинг</value>\n  </data>\n  <data name=\"TbSettingsSocksPort\" xml:space=\"preserve\">\n    <value>Порт Socks</value>\n  </data>\n  <data name=\"TbSettingsStartBoot\" xml:space=\"preserve\">\n    <value>Автозапуск</value>\n  </data>\n  <data name=\"TbSettingsStatistics\" xml:space=\"preserve\">\n    <value>Включить статистику (требуется перезагрузка)</value>\n  </data>\n  <data name=\"TbSettingsStatisticsFreshRate\" xml:space=\"preserve\">\n    <value>Частота обновления статистики в секундах</value>\n  </data>\n  <data name=\"TbSettingsSubConvert\" xml:space=\"preserve\">\n    <value>URL-адрес конверсии подписки</value>\n  </data>\n  <data name=\"TbSettingsSystemproxy\" xml:space=\"preserve\">\n    <value>Настройки системного прокси</value>\n  </data>\n  <data name=\"TbSettingsTLS13\" xml:space=\"preserve\">\n    <value>Включить протокол безопасности TLS v1.3 (обновление подписки)</value>\n  </data>\n  <data name=\"TbSettingsTrayMenuServersLimit\" xml:space=\"preserve\">\n    <value>Tray right-click menu servers display limit</value>\n  </data>\n  <data name=\"TbSettingsUdpEnabled\" xml:space=\"preserve\">\n    <value>Включить UDP</value>\n  </data>\n  <data name=\"TbSettingsUser\" xml:space=\"preserve\">\n    <value>Auth user</value>\n  </data>\n  <data name=\"TbClearSystemProxy\" xml:space=\"preserve\">\n    <value>Очистить системный прокси</value>\n  </data>\n  <data name=\"TbDisplayGUI\" xml:space=\"preserve\">\n    <value>Показать GUI</value>\n  </data>\n  <data name=\"TbGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>Настройка горячих клавиш</value>\n  </data>\n  <data name=\"TbGlobalHotkeySettingTip\" xml:space=\"preserve\">\n    <value>Установите непосредственно, нажав на клавиатуру, вступит в силу после перезапуска</value>\n  </data>\n  <data name=\"TbNotChangeSystemProxy\" xml:space=\"preserve\">\n    <value>Не изменять системный прокси</value>\n  </data>\n  <data name=\"TbReset\" xml:space=\"preserve\">\n    <value>Обнулить</value>\n  </data>\n  <data name=\"TbSetSystemProxy\" xml:space=\"preserve\">\n    <value>Установить системный прокси</value>\n  </data>\n  <data name=\"TbSystemProxyPac\" xml:space=\"preserve\">\n    <value>Режим PAC</value>\n  </data>\n  <data name=\"menuShareServer\" xml:space=\"preserve\">\n    <value>Поделиться сервером (Ctrl+F)</value>\n  </data>\n  <data name=\"menuRouting\" xml:space=\"preserve\">\n    <value>Маршрутизация</value>\n  </data>\n  <data name=\"NotRunAsAdmin\" xml:space=\"preserve\">\n    <value>Пользователь</value>\n  </data>\n  <data name=\"RunAsAdmin\" xml:space=\"preserve\">\n    <value>Администратор</value>\n  </data>\n  <data name=\"menuMoveBottom\" xml:space=\"preserve\">\n    <value>Спуститься вниз (B)</value>\n  </data>\n  <data name=\"menuMoveDown\" xml:space=\"preserve\">\n    <value>Вниз (D)</value>\n  </data>\n  <data name=\"menuMoveTop\" xml:space=\"preserve\">\n    <value>Подняться наверх (T)</value>\n  </data>\n  <data name=\"menuMoveUp\" xml:space=\"preserve\">\n    <value>Вверх (U)</value>\n  </data>\n  <data name=\"MsgFilterTitle\" xml:space=\"preserve\">\n    <value>Фильтр, поддерживает regex</value>\n  </data>\n  <data name=\"menuWebsiteItem\" xml:space=\"preserve\">\n    <value>{0} веб-сайт</value>\n  </data>\n  <data name=\"menuRoutingAdvanced\" xml:space=\"preserve\">\n    <value>Расширенная функция</value>\n  </data>\n  <data name=\"menuRoutingAdvancedAdd\" xml:space=\"preserve\">\n    <value>Добавить</value>\n  </data>\n  <data name=\"menuRoutingAdvancedImportRules\" xml:space=\"preserve\">\n    <value>Добавить расширенные правила</value>\n  </data>\n  <data name=\"menuRoutingAdvancedRemove\" xml:space=\"preserve\">\n    <value>Удалить выбранные</value>\n  </data>\n  <data name=\"menuRoutingAdvancedSetDefault\" xml:space=\"preserve\">\n    <value>Установить как активное правило</value>\n  </data>\n  <data name=\"menuRoutingBasic\" xml:space=\"preserve\">\n    <value>Основные функции</value>\n  </data>\n  <data name=\"menuRoutingBasicImportRules\" xml:space=\"preserve\">\n    <value>Импорт основных правил</value>\n  </data>\n  <data name=\"TbdomainMatcher\" xml:space=\"preserve\">\n    <value>Сопоставитель доменов</value>\n  </data>\n  <data name=\"TbdomainStrategy\" xml:space=\"preserve\">\n    <value>Доменная стратегия</value>\n  </data>\n  <data name=\"TbenableRoutingAdvanced\" xml:space=\"preserve\">\n    <value>Включить расширенные функции</value>\n  </data>\n  <data name=\"TbRoutingTabBlock\" xml:space=\"preserve\">\n    <value>3.Заблокировать домен или IP</value>\n  </data>\n  <data name=\"TbRoutingTabDirect\" xml:space=\"preserve\">\n    <value>2.Прямой домен или IP</value>\n  </data>\n  <data name=\"TbRoutingTabProxy\" xml:space=\"preserve\">\n    <value>1.Прокси-домен или IP</value>\n  </data>\n  <data name=\"TbRoutingTabRuleList\" xml:space=\"preserve\">\n    <value>Предустановленный список наборов правил</value>\n  </data>\n  <data name=\"TbRoutingTips\" xml:space=\"preserve\">\n    <value>* Установите правила, разделенные запятыми (,); Запятая в регулярке заменена на &lt;COMMA&gt;</value>\n  </data>\n  <data name=\"menuImportRulesFromClipboard\" xml:space=\"preserve\">\n    <value>Импорт правил из буфера обмена</value>\n  </data>\n  <data name=\"menuImportRulesFromFile\" xml:space=\"preserve\">\n    <value>Импорт правил из файла</value>\n  </data>\n  <data name=\"menuImportRulesFromUrl\" xml:space=\"preserve\">\n    <value>Импорт правил из URL</value>\n  </data>\n  <data name=\"menuRoutingRuleSetting\" xml:space=\"preserve\">\n    <value>Настройка правил</value>\n  </data>\n  <data name=\"menuRuleAdd\" xml:space=\"preserve\">\n    <value>Добавить правило</value>\n  </data>\n  <data name=\"menuRuleExportSelected\" xml:space=\"preserve\">\n    <value>Экспорт выделенных правил</value>\n  </data>\n  <data name=\"menuRuleList\" xml:space=\"preserve\">\n    <value>Список правил</value>\n  </data>\n  <data name=\"menuRuleRemove\" xml:space=\"preserve\">\n    <value>Удалить правила (Delete)</value>\n  </data>\n  <data name=\"menuRoutingRuleDetailsSetting\" xml:space=\"preserve\">\n    <value>RoutingRuleDetailsSetting</value>\n  </data>\n  <data name=\"TbAutoSort\" xml:space=\"preserve\">\n    <value>Домен и IP автоматически сортируются при сохранении</value>\n  </data>\n  <data name=\"TbRuleobjectDoc\" xml:space=\"preserve\">\n    <value>Ruleobject Doc</value>\n  </data>\n  <data name=\"TbDnsObjectDoc\" xml:space=\"preserve\">\n    <value>Поддержка DnsObject</value>\n  </data>\n  <data name=\"SubUrlTips\" xml:space=\"preserve\">\n    <value>Group please leave blank here</value>\n  </data>\n  <data name=\"TipChangeRouting\" xml:space=\"preserve\">\n    <value>Настройки маршрутизации изменены</value>\n  </data>\n  <data name=\"TipChangeSystemProxy\" xml:space=\"preserve\">\n    <value>Системные прокси изменены</value>\n  </data>\n  <data name=\"TbSettingsRouteOnly\" xml:space=\"preserve\">\n    <value>Только маршрут</value>\n  </data>\n  <data name=\"menuMixedTestServer\" xml:space=\"preserve\">\n    <value>Тест задержки и скорости (Ctrl+E)</value>\n  </data>\n  <data name=\"LvTestDelay\" xml:space=\"preserve\">\n    <value>Задержка (ms)</value>\n  </data>\n  <data name=\"LvTestSpeed\" xml:space=\"preserve\">\n    <value>Скорость (M/s)</value>\n  </data>\n  <data name=\"FailedToRunCore\" xml:space=\"preserve\">\n    <value>Не удалось запустить ядро, посмотрите логи</value>\n  </data>\n  <data name=\"LvFilter\" xml:space=\"preserve\">\n    <value>Remarks regular filter</value>\n  </data>\n  <data name=\"TbDisplayLog\" xml:space=\"preserve\">\n    <value>Показать логи</value>\n  </data>\n  <data name=\"menuImportOldGuiConfig\" xml:space=\"preserve\">\n    <value>Импортировать старый конфиг guiNConfig</value>\n  </data>\n  <data name=\"TbEnableTunAs\" xml:space=\"preserve\">\n    <value>Включить интерфейс</value>\n  </data>\n  <data name=\"TbSettingsNewPort4LAN\" xml:space=\"preserve\">\n    <value>Новый порт для локальной сети</value>\n  </data>\n  <data name=\"TbSettingsTunMode\" xml:space=\"preserve\">\n    <value>Настройки TunMode</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectIP\" xml:space=\"preserve\">\n    <value>Прямой IP CIDR, разделенный запятыми (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectProcess\" xml:space=\"preserve\">\n    <value>Имя процесса, разделенное запятыми (,)</value>\n  </data>\n  <data name=\"TbSettingsTunModeShowWindow\" xml:space=\"preserve\">\n    <value>Показать консоль</value>\n  </data>\n  <data name=\"menuMoveToGroup\" xml:space=\"preserve\">\n    <value>Перейти в группу</value>\n  </data>\n  <data name=\"TbSettingsTunModeCustomTemplate\" xml:space=\"preserve\">\n    <value>Пользовательский шаблон</value>\n  </data>\n  <data name=\"TbSettingsEnableDragDropSort\" xml:space=\"preserve\">\n    <value>Включить сортировку перетаскиванием сервера (требуется перезагрузка)</value>\n  </data>\n  <data name=\"TbAutoRefresh\" xml:space=\"preserve\">\n    <value>Автообновление</value>\n  </data>\n  <data name=\"SpeedtestingSkip\" xml:space=\"preserve\">\n    <value>Пропустить тест</value>\n  </data>\n  <data name=\"menuEditServer\" xml:space=\"preserve\">\n    <value>Редактировать сервер (Ctrl+D)</value>\n  </data>\n  <data name=\"TbSettingsDoubleClick2Activate\" xml:space=\"preserve\">\n    <value>Двойной клик чтобы сделать сервер активным</value>\n  </data>\n  <data name=\"SpeedtestingCompleted\" xml:space=\"preserve\">\n    <value>Тест завершен</value>\n  </data>\n  <data name=\"TbSettingsDefFingerprint\" xml:space=\"preserve\">\n    <value>TLS отпечаток по умлочанию</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgent\" xml:space=\"preserve\">\n    <value>User-Agent</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgentTips\" xml:space=\"preserve\">\n    <value>Этот параметр действителен только для TCP/HTTP и WS</value>\n  </data>\n  <data name=\"TbSettingsCurrentFontFamily\" xml:space=\"preserve\">\n    <value>Шрифт (требуется перезагрузка)</value>\n  </data>\n  <data name=\"TbSettingsCurrentFontFamilyTip\" xml:space=\"preserve\">\n    <value>Скопируйте файл шрифта TTF в каталог guiFonts, перезапустите настройки</value>\n  </data>\n  <data name=\"TbSettingsSocksPortTip\" xml:space=\"preserve\">\n    <value>HTTP port=socks port+1</value>\n  </data>\n  <data name=\"TbSettingsStartBootTip\" xml:space=\"preserve\">\n    <value>Установите это с правами администратора</value>\n  </data>\n  <data name=\"TbSettingsFontSize\" xml:space=\"preserve\">\n    <value>Размер шрифта</value>\n  </data>\n  <data name=\"TbSettingsEnableHWA\" xml:space=\"preserve\">\n    <value>Включить аппаратное ускорение (требуется перезагрузка)</value>\n  </data>\n  <data name=\"TbEnableProxy\" xml:space=\"preserve\">\n    <value>Active Proxy</value>\n  </data>\n</root>"
  },
  {
    "path": "v2rayN/v2rayN/Resx/ResUI.zh-Hans.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=\"BatchExportSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>批量导出订阅内容至剪贴板成功</value>\n  </data>\n  <data name=\"BatchExportURLSuccessfully\" xml:space=\"preserve\">\n    <value>批量导出分享URL至剪贴板成功</value>\n  </data>\n  <data name=\"CheckServerSettings\" xml:space=\"preserve\">\n    <value>请先检查服务器设置</value>\n  </data>\n  <data name=\"ConfigurationFormatIncorrect\" xml:space=\"preserve\">\n    <value>配置格式不正确</value>\n  </data>\n  <data name=\"CustomServerTips\" xml:space=\"preserve\">\n    <value>注意,自定义配置完全依赖您自己的配置，不能使用所有设置功能。如需使用系统代理请手动修改监听端口。</value>\n  </data>\n  <data name=\"Downloading\" xml:space=\"preserve\">\n    <value>下载开始...</value>\n  </data>\n  <data name=\"downloadSpeed\" xml:space=\"preserve\">\n    <value>下载</value>\n  </data>\n  <data name=\"DownloadYesNo\" xml:space=\"preserve\">\n    <value>是否下载? {0}</value>\n  </data>\n  <data name=\"FailedConversionConfiguration\" xml:space=\"preserve\">\n    <value>转换配置文件失败</value>\n  </data>\n  <data name=\"FailedGenDefaultConfiguration\" xml:space=\"preserve\">\n    <value>生成默认配置文件失败</value>\n  </data>\n  <data name=\"FailedGetDefaultConfiguration\" xml:space=\"preserve\">\n    <value>获取默认配置失败</value>\n  </data>\n  <data name=\"FailedImportedCustomServer\" xml:space=\"preserve\">\n    <value>导入自定义配置服务器失败</value>\n  </data>\n  <data name=\"FailedReadConfiguration\" xml:space=\"preserve\">\n    <value>读取配置文件失败</value>\n  </data>\n  <data name=\"FillCorrectServerPort\" xml:space=\"preserve\">\n    <value>请填写正确格式服务器端口</value>\n  </data>\n  <data name=\"FillKcpParameters\" xml:space=\"preserve\">\n    <value>请正确填写KCP参数</value>\n  </data>\n  <data name=\"FillLocalListeningPort\" xml:space=\"preserve\">\n    <value>请填写本地监听端口</value>\n  </data>\n  <data name=\"FillPassword\" xml:space=\"preserve\">\n    <value>请填写密码</value>\n  </data>\n  <data name=\"FillServerAddress\" xml:space=\"preserve\">\n    <value>请填写服务器地址</value>\n  </data>\n  <data name=\"FillUUID\" xml:space=\"preserve\">\n    <value>请填写用户ID</value>\n  </data>\n  <data name=\"IncorrectClientConfiguration\" xml:space=\"preserve\">\n    <value>不是正确的客户端配置文件，请检查</value>\n  </data>\n  <data name=\"Incorrectconfiguration\" xml:space=\"preserve\">\n    <value>不是正确的配置，请检查</value>\n  </data>\n  <data name=\"IncorrectServerConfiguration\" xml:space=\"preserve\">\n    <value>不是正确的服务端配置文件，请检查</value>\n  </data>\n  <data name=\"InitialConfiguration\" xml:space=\"preserve\">\n    <value>初始化配置</value>\n  </data>\n  <data name=\"IsLatestCore\" xml:space=\"preserve\">\n    <value>{0} 已是最新版本。</value>\n  </data>\n  <data name=\"IsLatestN\" xml:space=\"preserve\">\n    <value>{0} 已是最新版本。</value>\n  </data>\n  <data name=\"LvAddress\" xml:space=\"preserve\">\n    <value>地址</value>\n  </data>\n  <data name=\"LvEncryptionMethod\" xml:space=\"preserve\">\n    <value>加密方式</value>\n  </data>\n  <data name=\"LvPort\" xml:space=\"preserve\">\n    <value>端口</value>\n  </data>\n  <data name=\"LvServiceType\" xml:space=\"preserve\">\n    <value>类型</value>\n  </data>\n  <data name=\"LvSubscription\" xml:space=\"preserve\">\n    <value>订阅分组</value>\n  </data>\n  <data name=\"LvTodayDownloadDataAmount\" xml:space=\"preserve\">\n    <value>今日下载</value>\n  </data>\n  <data name=\"LvTodayUploadDataAmount\" xml:space=\"preserve\">\n    <value>今日上传</value>\n  </data>\n  <data name=\"LvTotalDownloadDataAmount\" xml:space=\"preserve\">\n    <value>总下载</value>\n  </data>\n  <data name=\"LvTotalUploadDataAmount\" xml:space=\"preserve\">\n    <value>总上传</value>\n  </data>\n  <data name=\"LvTransportProtocol\" xml:space=\"preserve\">\n    <value>传输协议</value>\n  </data>\n  <data name=\"MsgClearSubscription\" xml:space=\"preserve\">\n    <value>清除原订阅内容</value>\n  </data>\n  <data name=\"MsgDownloadV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>下载Core成功</value>\n  </data>\n  <data name=\"MsgFailedImportSubscription\" xml:space=\"preserve\">\n    <value>导入订阅内容失败</value>\n  </data>\n  <data name=\"MsgGetSubscriptionSuccessfully\" xml:space=\"preserve\">\n    <value>获取订阅内容成功</value>\n  </data>\n  <data name=\"MsgNoValidSubscription\" xml:space=\"preserve\">\n    <value>未设置有效的订阅</value>\n  </data>\n  <data name=\"MsgParsingSuccessfully\" xml:space=\"preserve\">\n    <value>解析{0}成功</value>\n  </data>\n  <data name=\"MsgStartGettingSubscriptions\" xml:space=\"preserve\">\n    <value>开始获取订阅内容</value>\n  </data>\n  <data name=\"MsgStartUpdating\" xml:space=\"preserve\">\n    <value>开始更新 {0}...</value>\n  </data>\n  <data name=\"MsgSubscriptionDecodingFailed\" xml:space=\"preserve\">\n    <value>无效的订阅内容</value>\n  </data>\n  <data name=\"MsgUnpacking\" xml:space=\"preserve\">\n    <value>正在解压......</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionEnd\" xml:space=\"preserve\">\n    <value>未更新任何内容</value>\n  </data>\n  <data name=\"MsgUpdateSubscriptionStart\" xml:space=\"preserve\">\n    <value>更新订阅开始</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfully\" xml:space=\"preserve\">\n    <value>更新Core成功</value>\n  </data>\n  <data name=\"MsgUpdateV2rayCoreSuccessfullyMore\" xml:space=\"preserve\">\n    <value>更新Core成功！正在重启服务...</value>\n  </data>\n  <data name=\"NonvmessOrssProtocol\" xml:space=\"preserve\">\n    <value>非VMess或ss协议</value>\n  </data>\n  <data name=\"NonVmessService\" xml:space=\"preserve\">\n    <value>非标准服务，此功能无效</value>\n  </data>\n  <data name=\"NotFoundCore\" xml:space=\"preserve\">\n    <value>在文件夹 ({0}) 下未找到Core文件 (文件名:{1})，请下载后放入文件夹，下载地址: {2}</value>\n  </data>\n  <data name=\"NoValidQRcodeFound\" xml:space=\"preserve\">\n    <value>扫描完成,未发现有效二维码</value>\n  </data>\n  <data name=\"OperationFailed\" xml:space=\"preserve\">\n    <value>操作失败，请检查重试</value>\n  </data>\n  <data name=\"PleaseFillRemarks\" xml:space=\"preserve\">\n    <value>请填写别名</value>\n  </data>\n  <data name=\"PleaseSelectEncryption\" xml:space=\"preserve\">\n    <value>请选择加密方式</value>\n  </data>\n  <data name=\"PleaseSelectProtocol\" xml:space=\"preserve\">\n    <value>请选择协议</value>\n  </data>\n  <data name=\"PleaseSelectServer\" xml:space=\"preserve\">\n    <value>请先选择服务器</value>\n  </data>\n  <data name=\"RemoveDuplicateServerResult\" xml:space=\"preserve\">\n    <value>服务器去重完成。原数量: {0}，现数量: {1}</value>\n  </data>\n  <data name=\"RemoveServer\" xml:space=\"preserve\">\n    <value>是否确定移除服务器?</value>\n  </data>\n  <data name=\"SaveClientConfigurationIn\" xml:space=\"preserve\">\n    <value>客户端配置文件保存在:{0}</value>\n  </data>\n  <data name=\"StartService\" xml:space=\"preserve\">\n    <value>启动服务({0})...</value>\n  </data>\n  <data name=\"SuccessfulConfiguration\" xml:space=\"preserve\">\n    <value>配置成功\n{0}</value>\n  </data>\n  <data name=\"SuccessfullyImportedCustomServer\" xml:space=\"preserve\">\n    <value>成功导入自定义配置服务器</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaClipboard\" xml:space=\"preserve\">\n    <value>成功从剪贴板导入 {0} 个服务器</value>\n  </data>\n  <data name=\"SuccessfullyImportedServerViaScan\" xml:space=\"preserve\">\n    <value>扫描导入URL成功</value>\n  </data>\n  <data name=\"TestMeOutput\" xml:space=\"preserve\">\n    <value>当前服务的真连接延迟: {0} ms</value>\n  </data>\n  <data name=\"OperationSuccess\" xml:space=\"preserve\">\n    <value>操作成功</value>\n  </data>\n  <data name=\"PleaseSelectRules\" xml:space=\"preserve\">\n    <value>请先选择规则</value>\n  </data>\n  <data name=\"RemoveRules\" xml:space=\"preserve\">\n    <value>是否确定移除规则?</value>\n  </data>\n  <data name=\"RoutingRuleDetailRequiredTips\" xml:space=\"preserve\">\n    <value>{0},必填其中一项.</value>\n  </data>\n  <data name=\"LvRemarks\" xml:space=\"preserve\">\n    <value>别名</value>\n  </data>\n  <data name=\"LvUrl\" xml:space=\"preserve\">\n    <value>可选地址(Url)</value>\n  </data>\n  <data name=\"LvCount\" xml:space=\"preserve\">\n    <value>数量</value>\n  </data>\n  <data name=\"MsgNeedUrl\" xml:space=\"preserve\">\n    <value>请填写Url</value>\n  </data>\n  <data name=\"AddBatchRoutingRulesYesNo\" xml:space=\"preserve\">\n    <value>是否追加规则?选择是则追加,选择否则替换</value>\n  </data>\n  <data name=\"MsgDownloadGeoFileSuccessfully\" xml:space=\"preserve\">\n    <value>下载 GeoFile: {0} 成功</value>\n  </data>\n  <data name=\"MsgInformationTitle\" xml:space=\"preserve\">\n    <value>信息</value>\n  </data>\n  <data name=\"LvCustomIcon\" xml:space=\"preserve\">\n    <value>自定义图标</value>\n  </data>\n  <data name=\"FillCorrectDNSText\" xml:space=\"preserve\">\n    <value>请填写正确的自定义DNS</value>\n  </data>\n  <data name=\"TransportPathTip1\" xml:space=\"preserve\">\n    <value>*ws path</value>\n  </data>\n  <data name=\"TransportPathTip2\" xml:space=\"preserve\">\n    <value>*h2 path</value>\n  </data>\n  <data name=\"TransportPathTip3\" xml:space=\"preserve\">\n    <value>*QUIC 加密密钥</value>\n  </data>\n  <data name=\"TransportPathTip4\" xml:space=\"preserve\">\n    <value>*grpc serviceName</value>\n  </data>\n  <data name=\"TransportRequestHostTip1\" xml:space=\"preserve\">\n    <value>*http host中间逗号(,)分隔</value>\n  </data>\n  <data name=\"TransportRequestHostTip2\" xml:space=\"preserve\">\n    <value>*ws host</value>\n  </data>\n  <data name=\"TransportRequestHostTip3\" xml:space=\"preserve\">\n    <value>*h2 host中间逗号(,)分隔</value>\n  </data>\n  <data name=\"TransportRequestHostTip4\" xml:space=\"preserve\">\n    <value>*QUIC 加密方式</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip1\" xml:space=\"preserve\">\n    <value>*tcp伪装类型</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip2\" xml:space=\"preserve\">\n    <value>*kcp伪装类型</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip3\" xml:space=\"preserve\">\n    <value>*QUIC伪装类型</value>\n  </data>\n  <data name=\"TransportHeaderTypeTip4\" xml:space=\"preserve\">\n    <value>*grpc 模式</value>\n  </data>\n  <data name=\"LvTLS\" xml:space=\"preserve\">\n    <value>TLS</value>\n  </data>\n  <data name=\"TransportPathTip5\" xml:space=\"preserve\">\n    <value>*Kcp seed</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeyFailed\" xml:space=\"preserve\">\n    <value>注册全局热键 {0} 失败,原因 {1}</value>\n  </data>\n  <data name=\"RegisterGlobalHotkeySuccessfully\" xml:space=\"preserve\">\n    <value>注册全局热键 {0} 成功</value>\n  </data>\n  <data name=\"UngroupedServers\" xml:space=\"preserve\">\n    <value>未分组服务器</value>\n  </data>\n  <data name=\"AllGroupServers\" xml:space=\"preserve\">\n    <value>所有</value>\n  </data>\n  <data name=\"FillServerAddressCustom\" xml:space=\"preserve\">\n    <value>请浏览导入服务器配置</value>\n  </data>\n  <data name=\"SystemProxy\" xml:space=\"preserve\">\n    <value>系统代理</value>\n  </data>\n  <data name=\"Speedtesting\" xml:space=\"preserve\">\n    <value>测试中...</value>\n  </data>\n  <data name=\"TooManyServersTip\" xml:space=\"preserve\">\n    <value>服务器太多，请打开主界面操作</value>\n  </data>\n  <data name=\"LabLAN\" xml:space=\"preserve\">\n    <value>局域网</value>\n  </data>\n  <data name=\"LabLocal\" xml:space=\"preserve\">\n    <value>本地</value>\n  </data>\n  <data name=\"MsgNothingUpdated\" xml:space=\"preserve\">\n    <value>没有更新任何内容</value>\n  </data>\n  <data name=\"MsgStartProgramAsAdmin\" xml:space=\"preserve\">\n    <value>为此，程序必须在 \"Administrator\" 中运行</value>\n  </data>\n  <data name=\"MsgDeepLinkIsInvalid\" xml:space=\"preserve\">\n    <value>链接无效</value>\n  </data>\n  <data name=\"MsgProgramNeedsRestarting\" xml:space=\"preserve\">\n    <value>要执行此操作，必须重新启动程序 !</value>\n  </data>\n  <data name=\"MsgServerTitle\" xml:space=\"preserve\">\n    <value>服务器过滤器，按回车执行</value>\n  </data>\n  <data name=\"menuCheckUpdate\" xml:space=\"preserve\">\n    <value>检查更新</value>\n  </data>\n  <data name=\"menuClose\" xml:space=\"preserve\">\n    <value>关闭</value>\n  </data>\n  <data name=\"menuExit\" xml:space=\"preserve\">\n    <value>退出</value>\n  </data>\n  <data name=\"menuGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>全局热键设置</value>\n  </data>\n  <data name=\"menuHelp\" xml:space=\"preserve\">\n    <value>帮助</value>\n  </data>\n  <data name=\"menuOptionSetting\" xml:space=\"preserve\">\n    <value>参数设置</value>\n  </data>\n  <data name=\"menuPromotion\" xml:space=\"preserve\">\n    <value>推广</value>\n  </data>\n  <data name=\"menuReload\" xml:space=\"preserve\">\n    <value>重启服务</value>\n  </data>\n  <data name=\"menuRoutingSetting\" xml:space=\"preserve\">\n    <value>路由设置</value>\n  </data>\n  <data name=\"menuServers\" xml:space=\"preserve\">\n    <value>服务器</value>\n  </data>\n  <data name=\"menuSetting\" xml:space=\"preserve\">\n    <value>设置</value>\n  </data>\n  <data name=\"menuSubGroupUpdate\" xml:space=\"preserve\">\n    <value>更新当前订阅(不通过代理)</value>\n  </data>\n  <data name=\"menuSubGroupUpdateViaProxy\" xml:space=\"preserve\">\n    <value>更新当前订阅(通过代理)</value>\n  </data>\n  <data name=\"menuSubscription\" xml:space=\"preserve\">\n    <value>订阅分组</value>\n  </data>\n  <data name=\"menuSubSetting\" xml:space=\"preserve\">\n    <value>订阅分组设置</value>\n  </data>\n  <data name=\"menuSubUpdate\" xml:space=\"preserve\">\n    <value>更新全部订阅(不通过代理)</value>\n  </data>\n  <data name=\"menuSubUpdateViaProxy\" xml:space=\"preserve\">\n    <value>更新全部订阅(通过代理)</value>\n  </data>\n  <data name=\"menuSystemproxy\" xml:space=\"preserve\">\n    <value>系统代理</value>\n  </data>\n  <data name=\"menuSystemProxyClear\" xml:space=\"preserve\">\n    <value>清除系统代理</value>\n  </data>\n  <data name=\"menuSystemProxyNothing\" xml:space=\"preserve\">\n    <value>不改变系统代理</value>\n  </data>\n  <data name=\"menuSystemProxyPac\" xml:space=\"preserve\">\n    <value>Pac模式</value>\n  </data>\n  <data name=\"menuSystemProxySet\" xml:space=\"preserve\">\n    <value>自动配置系统代理</value>\n  </data>\n  <data name=\"TbSettingsColor\" xml:space=\"preserve\">\n    <value>颜色</value>\n  </data>\n  <data name=\"TbSettingsColorMode\" xml:space=\"preserve\">\n    <value>暗黑模式</value>\n  </data>\n  <data name=\"TbSettingsLanguage\" xml:space=\"preserve\">\n    <value>语言(重启)</value>\n  </data>\n  <data name=\"menuAddServerViaClipboard\" xml:space=\"preserve\">\n    <value>从剪贴板导入批量URL (Ctrl+V)</value>\n  </data>\n  <data name=\"menuAddServerViaScan\" xml:space=\"preserve\">\n    <value>扫描屏幕上的二维码 (Ctrl+S)</value>\n  </data>\n  <data name=\"menuCopyServer\" xml:space=\"preserve\">\n    <value>克隆所选服务器</value>\n  </data>\n  <data name=\"menuRemoveDuplicateServer\" xml:space=\"preserve\">\n    <value>移除重复的服务器</value>\n  </data>\n  <data name=\"menuRemoveServer\" xml:space=\"preserve\">\n    <value>移除所选服务器(多选) (Delete)</value>\n  </data>\n  <data name=\"menuSetDefaultServer\" xml:space=\"preserve\">\n    <value>设为活动服务器 (Enter)</value>\n  </data>\n  <data name=\"menuClearServerStatistics\" xml:space=\"preserve\">\n    <value>清除所有服务统计数据</value>\n  </data>\n  <data name=\"menuPingServer\" xml:space=\"preserve\">\n    <value>测试服务器延迟Ping(多选) (Ctrl+P)</value>\n  </data>\n  <data name=\"menuRealPingServer\" xml:space=\"preserve\">\n    <value>测试服务器真连接延迟(多选) (Ctrl+R)</value>\n  </data>\n  <data name=\"menuSortServerResult\" xml:space=\"preserve\">\n    <value>按测试结果排序</value>\n  </data>\n  <data name=\"menuSpeedServer\" xml:space=\"preserve\">\n    <value>测试服务器速度(多选) (Ctrl+T)</value>\n  </data>\n  <data name=\"menuTcpingServer\" xml:space=\"preserve\">\n    <value>测试服务器延迟Tcping(多选) (Ctrl+O)</value>\n  </data>\n  <data name=\"menuTestMe\" xml:space=\"preserve\">\n    <value>测试当前服务状态</value>\n  </data>\n  <data name=\"menuExport2ClientConfig\" xml:space=\"preserve\">\n    <value>导出所选服务器为客户端配置</value>\n  </data>\n  <data name=\"menuExport2ShareUrl\" xml:space=\"preserve\">\n    <value>批量导出分享URL至剪贴板(多选) (Ctrl+C)</value>\n  </data>\n  <data name=\"menuExport2SubContent\" xml:space=\"preserve\">\n    <value>批量导出订阅内容至剪贴板(多选)</value>\n  </data>\n  <data name=\"menuAddCustomServer\" xml:space=\"preserve\">\n    <value>添加自定义配置服务器</value>\n  </data>\n  <data name=\"menuAddShadowsocksServer\" xml:space=\"preserve\">\n    <value>添加[Shadowsocks]服务器</value>\n  </data>\n  <data name=\"menuAddSocksServer\" xml:space=\"preserve\">\n    <value>添加[Socks]服务器</value>\n  </data>\n  <data name=\"menuAddTrojanServer\" xml:space=\"preserve\">\n    <value>添加[Trojan]服务器</value>\n  </data>\n  <data name=\"menuAddVlessServer\" xml:space=\"preserve\">\n    <value>添加[VLESS]服务器</value>\n  </data>\n  <data name=\"menuAddVmessServer\" xml:space=\"preserve\">\n    <value>添加[VMess]服务器</value>\n  </data>\n  <data name=\"menuSelectAll\" xml:space=\"preserve\">\n    <value>全选 (Ctrl+A)</value>\n  </data>\n  <data name=\"menuMsgViewClear\" xml:space=\"preserve\">\n    <value>清除所有</value>\n  </data>\n  <data name=\"menuMsgViewCopy\" xml:space=\"preserve\">\n    <value>复制 (Ctrl+C)</value>\n  </data>\n  <data name=\"menuMsgViewCopyAll\" xml:space=\"preserve\">\n    <value>复制所有</value>\n  </data>\n  <data name=\"menuMsgViewFilter\" xml:space=\"preserve\">\n    <value>设置信息过滤器</value>\n  </data>\n  <data name=\"menuMsgViewSelectAll\" xml:space=\"preserve\">\n    <value>全选 (Ctrl+A)</value>\n  </data>\n  <data name=\"menuSubAdd\" xml:space=\"preserve\">\n    <value>添加</value>\n  </data>\n  <data name=\"menuSubDelete\" xml:space=\"preserve\">\n    <value>删除</value>\n  </data>\n  <data name=\"menuSubEdit\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"menuSubShare\" xml:space=\"preserve\">\n    <value>分享</value>\n  </data>\n  <data name=\"LvEnabled\" xml:space=\"preserve\">\n    <value>启用更新</value>\n  </data>\n  <data name=\"LvSort\" xml:space=\"preserve\">\n    <value>排序</value>\n  </data>\n  <data name=\"LvUserAgent\" xml:space=\"preserve\">\n    <value>User Agent(可选)</value>\n  </data>\n  <data name=\"TbCancel\" xml:space=\"preserve\">\n    <value>取消</value>\n  </data>\n  <data name=\"TbConfirm\" xml:space=\"preserve\">\n    <value>确定</value>\n  </data>\n  <data name=\"GbTransport\" xml:space=\"preserve\">\n    <value>底层传输方式(transport)</value>\n  </data>\n  <data name=\"TbAddress\" xml:space=\"preserve\">\n    <value>地址(address)</value>\n  </data>\n  <data name=\"TbAllowInsecure\" xml:space=\"preserve\">\n    <value>跳过证书验证(allowInsecure)</value>\n  </data>\n  <data name=\"TbAlpn\" xml:space=\"preserve\">\n    <value>Alpn</value>\n  </data>\n  <data name=\"TbAlterId\" xml:space=\"preserve\">\n    <value>额外ID(alterId)</value>\n  </data>\n  <data name=\"TbFingerprint\" xml:space=\"preserve\">\n    <value>Fingerprint</value>\n  </data>\n  <data name=\"TbHeaderType\" xml:space=\"preserve\">\n    <value>伪装类型(type)</value>\n  </data>\n  <data name=\"TbId\" xml:space=\"preserve\">\n    <value>用户ID(id)</value>\n  </data>\n  <data name=\"TbNetwork\" xml:space=\"preserve\">\n    <value>传输协议(network)</value>\n  </data>\n  <data name=\"TbPath\" xml:space=\"preserve\">\n    <value>路径(path)</value>\n  </data>\n  <data name=\"TbPort\" xml:space=\"preserve\">\n    <value>端口(port)</value>\n  </data>\n  <data name=\"TbRemarks\" xml:space=\"preserve\">\n    <value>别名(remarks)</value>\n  </data>\n  <data name=\"TbRequestHost\" xml:space=\"preserve\">\n    <value>伪装域名(host)</value>\n  </data>\n  <data name=\"TbSecurity\" xml:space=\"preserve\">\n    <value>加密方式(security)</value>\n  </data>\n  <data name=\"TbSNI\" xml:space=\"preserve\">\n    <value>SNI</value>\n  </data>\n  <data name=\"TbStreamSecurity\" xml:space=\"preserve\">\n    <value>传输层安全(TLS)</value>\n  </data>\n  <data name=\"TipNetwork\" xml:space=\"preserve\">\n    <value>*默认tcp,选错会无法连接</value>\n  </data>\n  <data name=\"TbCoreType\" xml:space=\"preserve\">\n    <value>Core类型</value>\n  </data>\n  <data name=\"TbFlow5\" xml:space=\"preserve\">\n    <value>流控(flow)</value>\n  </data>\n  <data name=\"TbGUID\" xml:space=\"preserve\">\n    <value>生成</value>\n  </data>\n  <data name=\"TbId3\" xml:space=\"preserve\">\n    <value>密码(password)</value>\n  </data>\n  <data name=\"TbId4\" xml:space=\"preserve\">\n    <value>密码(可选)</value>\n  </data>\n  <data name=\"TbId5\" xml:space=\"preserve\">\n    <value>用户ID(id)</value>\n  </data>\n  <data name=\"TbSecurity3\" xml:space=\"preserve\">\n    <value>加密方式(encryption)</value>\n  </data>\n  <data name=\"TbSecurity4\" xml:space=\"preserve\">\n    <value>用户名(可选)</value>\n  </data>\n  <data name=\"TbSecurity5\" xml:space=\"preserve\">\n    <value>加密方式(encryption)</value>\n  </data>\n  <data name=\"TbPreSocksPort\" xml:space=\"preserve\">\n    <value>Socks端口</value>\n  </data>\n  <data name=\"TipPreSocksPort\" xml:space=\"preserve\">\n    <value>* 自定义配置的Socks端口值，可不设置；当设置此值后，将使用Sing-box额外启动一个前置Socks服务，提供分流和速度显示等功能</value>\n  </data>\n  <data name=\"TbBrowse\" xml:space=\"preserve\">\n    <value>浏览</value>\n  </data>\n  <data name=\"TbEdit\" xml:space=\"preserve\">\n    <value>编辑</value>\n  </data>\n  <data name=\"TbSettingsAdvancedProtocol\" xml:space=\"preserve\">\n    <value>高级代理设置, 协议选择(可选)</value>\n  </data>\n  <data name=\"TbSettingsAllowLAN\" xml:space=\"preserve\">\n    <value>允许来自局域网的连接</value>\n  </data>\n  <data name=\"TbSettingsAutoHideStartup\" xml:space=\"preserve\">\n    <value>启动后隐藏窗口</value>\n  </data>\n  <data name=\"TbSettingsAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>自动更新Geo文件的间隔(单位小时)</value>\n  </data>\n  <data name=\"TbSettingsCore\" xml:space=\"preserve\">\n    <value>Core: 基础设置</value>\n  </data>\n  <data name=\"TbSettingsCoreDns\" xml:space=\"preserve\">\n    <value>V2ray DNS设置</value>\n  </data>\n  <data name=\"TbSettingsCoreKcp\" xml:space=\"preserve\">\n    <value>Core: KCP设置</value>\n  </data>\n  <data name=\"TbSettingsCoreType\" xml:space=\"preserve\">\n    <value>Core类型设置</value>\n  </data>\n  <data name=\"TbSettingsDefAllowInsecure\" xml:space=\"preserve\">\n    <value>默认跳过证书验证(allowInsecure)</value>\n  </data>\n  <data name=\"TbSettingsDomainStrategy4Freedom\" xml:space=\"preserve\">\n    <value>Outbound Freedom domainStrategy</value>\n  </data>\n  <data name=\"TbSettingsEnableAutoAdjustMainLvColWidth\" xml:space=\"preserve\">\n    <value>自动调整服务器列宽在更新订阅后</value>\n  </data>\n  <data name=\"TbSettingsEnableCheckPreReleaseUpdate\" xml:space=\"preserve\">\n    <value>检查Pre-Release更新(请谨慎启用)</value>\n  </data>\n  <data name=\"TbSettingsException\" xml:space=\"preserve\">\n    <value>例外</value>\n  </data>\n  <data name=\"TbSettingsExceptionTip\" xml:space=\"preserve\">\n    <value>例外. 对于下列字符开头的地址不使用代理配置文件:使用分号(;)分隔</value>\n  </data>\n  <data name=\"TbSettingsHttpPort\" xml:space=\"preserve\">\n    <value>本地http监听端口</value>\n  </data>\n  <data name=\"TbSettingsIgnoreGeoUpdateCore\" xml:space=\"preserve\">\n    <value>更新Core时忽略Geo文件</value>\n  </data>\n  <data name=\"TbSettingsKeepOlderDedupl\" xml:space=\"preserve\">\n    <value>去重时保留序号较小的项</value>\n  </data>\n  <data name=\"TbSettingsLogEnabled\" xml:space=\"preserve\">\n    <value>启用日志</value>\n  </data>\n  <data name=\"TbSettingsLogLevel\" xml:space=\"preserve\">\n    <value>日志等级</value>\n  </data>\n  <data name=\"TbSettingsMuxEnabled\" xml:space=\"preserve\">\n    <value>开启Mux多路复用</value>\n  </data>\n  <data name=\"TbSettingsN\" xml:space=\"preserve\">\n    <value>v2rayN 设置</value>\n  </data>\n  <data name=\"TbSettingsPass\" xml:space=\"preserve\">\n    <value>认证密码</value>\n  </data>\n  <data name=\"TbSettingsRemoteDNS\" xml:space=\"preserve\">\n    <value>自定义DNS(可多个,用逗号(,)分隔)</value>\n  </data>\n  <data name=\"TbSettingsSetUWP\" xml:space=\"preserve\">\n    <value>解除Win10 UWP应用回环代理限制</value>\n  </data>\n  <data name=\"TbSettingsSniffingEnabled\" xml:space=\"preserve\">\n    <value>开启流量探测</value>\n  </data>\n  <data name=\"TbSettingsSocksPort\" xml:space=\"preserve\">\n    <value>本地socks监听端口</value>\n  </data>\n  <data name=\"TbSettingsStartBoot\" xml:space=\"preserve\">\n    <value>开机启动(可能会不成功)</value>\n  </data>\n  <data name=\"TbSettingsStatistics\" xml:space=\"preserve\">\n    <value>启用统计(实时网速显示，需重启)</value>\n  </data>\n  <data name=\"TbSettingsStatisticsFreshRate\" xml:space=\"preserve\">\n    <value>统计刷新频率(单位秒)</value>\n  </data>\n  <data name=\"TbSettingsSubConvert\" xml:space=\"preserve\">\n    <value>订阅转换网址(可选)</value>\n  </data>\n  <data name=\"TbSettingsSystemproxy\" xml:space=\"preserve\">\n    <value>系统代理设置</value>\n  </data>\n  <data name=\"TbSettingsTLS13\" xml:space=\"preserve\">\n    <value>启用安全协议TLS v1.3 (订阅/检查更新)</value>\n  </data>\n  <data name=\"TbSettingsTrayMenuServersLimit\" xml:space=\"preserve\">\n    <value>托盘右键菜单服务器展示数量限制</value>\n  </data>\n  <data name=\"TbSettingsUdpEnabled\" xml:space=\"preserve\">\n    <value>开启UDP</value>\n  </data>\n  <data name=\"TbSettingsUser\" xml:space=\"preserve\">\n    <value>认证用户名</value>\n  </data>\n  <data name=\"TbClearSystemProxy\" xml:space=\"preserve\">\n    <value>清除系统代理</value>\n  </data>\n  <data name=\"TbDisplayGUI\" xml:space=\"preserve\">\n    <value>显示主界面</value>\n  </data>\n  <data name=\"TbGlobalHotkeySetting\" xml:space=\"preserve\">\n    <value>全局热键设置</value>\n  </data>\n  <data name=\"TbGlobalHotkeySettingTip\" xml:space=\"preserve\">\n    <value>直接按键盘进行设置, 重启后生效</value>\n  </data>\n  <data name=\"TbNotChangeSystemProxy\" xml:space=\"preserve\">\n    <value>不改变系统代理</value>\n  </data>\n  <data name=\"TbReset\" xml:space=\"preserve\">\n    <value>重置</value>\n  </data>\n  <data name=\"TbSetSystemProxy\" xml:space=\"preserve\">\n    <value>自动配置系统代理</value>\n  </data>\n  <data name=\"TbSystemProxyPac\" xml:space=\"preserve\">\n    <value>Pac模式</value>\n  </data>\n  <data name=\"menuShareServer\" xml:space=\"preserve\">\n    <value>分享服务器 (Ctrl+F)</value>\n  </data>\n  <data name=\"menuRouting\" xml:space=\"preserve\">\n    <value>路由</value>\n  </data>\n  <data name=\"NotRunAsAdmin\" xml:space=\"preserve\">\n    <value>以非管理员身份运行</value>\n  </data>\n  <data name=\"RunAsAdmin\" xml:space=\"preserve\">\n    <value>以管理员身份运行</value>\n  </data>\n  <data name=\"menuMoveBottom\" xml:space=\"preserve\">\n    <value>下移至底 (B)</value>\n  </data>\n  <data name=\"menuMoveDown\" xml:space=\"preserve\">\n    <value>下移 (D)</value>\n  </data>\n  <data name=\"menuMoveTop\" xml:space=\"preserve\">\n    <value>上移至顶 (T)</value>\n  </data>\n  <data name=\"menuMoveUp\" xml:space=\"preserve\">\n    <value>上移 (U)</value>\n  </data>\n  <data name=\"MsgFilterTitle\" xml:space=\"preserve\">\n    <value>过滤器, 支持正则</value>\n  </data>\n  <data name=\"menuWebsiteItem\" xml:space=\"preserve\">\n    <value>{0} 官网</value>\n  </data>\n  <data name=\"menuRoutingAdvanced\" xml:space=\"preserve\">\n    <value>高级功能</value>\n  </data>\n  <data name=\"menuRoutingAdvancedAdd\" xml:space=\"preserve\">\n    <value>添加规则集</value>\n  </data>\n  <data name=\"menuRoutingAdvancedImportRules\" xml:space=\"preserve\">\n    <value>一键导入高级规则</value>\n  </data>\n  <data name=\"menuRoutingAdvancedRemove\" xml:space=\"preserve\">\n    <value>移除所选规则 (Delete)</value>\n  </data>\n  <data name=\"menuRoutingAdvancedSetDefault\" xml:space=\"preserve\">\n    <value>设为活动规则 (Enter)</value>\n  </data>\n  <data name=\"menuRoutingBasic\" xml:space=\"preserve\">\n    <value>基础功能</value>\n  </data>\n  <data name=\"menuRoutingBasicImportRules\" xml:space=\"preserve\">\n    <value>一键导入基础规则</value>\n  </data>\n  <data name=\"TbdomainMatcher\" xml:space=\"preserve\">\n    <value>域名匹配算法</value>\n  </data>\n  <data name=\"TbdomainStrategy\" xml:space=\"preserve\">\n    <value>域名解析策略</value>\n  </data>\n  <data name=\"TbenableRoutingAdvanced\" xml:space=\"preserve\">\n    <value>启用高级功能</value>\n  </data>\n  <data name=\"TbRoutingTabBlock\" xml:space=\"preserve\">\n    <value>3.阻止的Domain或IP</value>\n  </data>\n  <data name=\"TbRoutingTabDirect\" xml:space=\"preserve\">\n    <value>2.直连的Domain或IP</value>\n  </data>\n  <data name=\"TbRoutingTabProxy\" xml:space=\"preserve\">\n    <value>1.代理的Domain或IP</value>\n  </data>\n  <data name=\"TbRoutingTabRuleList\" xml:space=\"preserve\">\n    <value>预定义规则集列表</value>\n  </data>\n  <data name=\"TbRoutingTips\" xml:space=\"preserve\">\n    <value>*设置的路由规则,用逗号(,)分隔;正则中的逗号用&lt;COMMA&gt;替代</value>\n  </data>\n  <data name=\"menuImportRulesFromClipboard\" xml:space=\"preserve\">\n    <value>从剪贴板中导入规则</value>\n  </data>\n  <data name=\"menuImportRulesFromFile\" xml:space=\"preserve\">\n    <value>从文件中导入规则</value>\n  </data>\n  <data name=\"menuImportRulesFromUrl\" xml:space=\"preserve\">\n    <value>从订阅Url中导入规则</value>\n  </data>\n  <data name=\"menuRoutingRuleSetting\" xml:space=\"preserve\">\n    <value>规则集设置</value>\n  </data>\n  <data name=\"menuRuleAdd\" xml:space=\"preserve\">\n    <value>添加规则</value>\n  </data>\n  <data name=\"menuRuleExportSelected\" xml:space=\"preserve\">\n    <value>导出所选规则至剪贴板</value>\n  </data>\n  <data name=\"menuRuleList\" xml:space=\"preserve\">\n    <value>规则列表</value>\n  </data>\n  <data name=\"menuRuleRemove\" xml:space=\"preserve\">\n    <value>移除所选规则 (Delete)</value>\n  </data>\n  <data name=\"menuRoutingRuleDetailsSetting\" xml:space=\"preserve\">\n    <value>路由规则详情设置</value>\n  </data>\n  <data name=\"TbAutoSort\" xml:space=\"preserve\">\n    <value>保存时Domain和IP自动排序</value>\n  </data>\n  <data name=\"TbRuleobjectDoc\" xml:space=\"preserve\">\n    <value>规则详细说明文档</value>\n  </data>\n  <data name=\"TbDnsObjectDoc\" xml:space=\"preserve\">\n    <value>支持填写DnsObject,JSON格式，点击查看文档</value>\n  </data>\n  <data name=\"SubUrlTips\" xml:space=\"preserve\">\n    <value>普通分组此处请留空</value>\n  </data>\n  <data name=\"TipChangeRouting\" xml:space=\"preserve\">\n    <value>路由设置改变</value>\n  </data>\n  <data name=\"TipChangeSystemProxy\" xml:space=\"preserve\">\n    <value>系统代理设置改变</value>\n  </data>\n  <data name=\"TbSettingsRouteOnly\" xml:space=\"preserve\">\n    <value>RouteOnly</value>\n  </data>\n  <data name=\"menuMixedTestServer\" xml:space=\"preserve\">\n    <value>一键多线程测试延迟和速度 (Ctrl+E)</value>\n  </data>\n  <data name=\"LvTestDelay\" xml:space=\"preserve\">\n    <value>延迟(ms)</value>\n  </data>\n  <data name=\"LvTestSpeed\" xml:space=\"preserve\">\n    <value>速度(M/s)</value>\n  </data>\n  <data name=\"FailedToRunCore\" xml:space=\"preserve\">\n    <value>运行Core失败，请看日志</value>\n  </data>\n  <data name=\"LvFilter\" xml:space=\"preserve\">\n    <value>别名正则过滤</value>\n  </data>\n  <data name=\"TbDisplayLog\" xml:space=\"preserve\">\n    <value>显示日志</value>\n  </data>\n  <data name=\"menuImportOldGuiConfig\" xml:space=\"preserve\">\n    <value>导入旧的配置文件guiNConfig</value>\n  </data>\n  <data name=\"TbEnableTunAs\" xml:space=\"preserve\">\n    <value>启用Tun模式</value>\n  </data>\n  <data name=\"TbSettingsNewPort4LAN\" xml:space=\"preserve\">\n    <value>为局域网开启新的端口</value>\n  </data>\n  <data name=\"TbSettingsTunMode\" xml:space=\"preserve\">\n    <value>Tun模式设置</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectIP\" xml:space=\"preserve\">\n    <value>直连的IP CIDR，用逗号(,)分隔</value>\n  </data>\n  <data name=\"TbSettingsTunModeDirectProcess\" xml:space=\"preserve\">\n    <value>直连的进程名，用逗号(,)分隔</value>\n  </data>\n  <data name=\"TbSettingsTunModeShowWindow\" xml:space=\"preserve\">\n    <value>显示控制台</value>\n  </data>\n  <data name=\"menuMoveToGroup\" xml:space=\"preserve\">\n    <value>移至订阅分组</value>\n  </data>\n  <data name=\"TbSettingsTunModeCustomTemplate\" xml:space=\"preserve\">\n    <value>自定义配置模板</value>\n  </data>\n  <data name=\"TbSettingsEnableDragDropSort\" xml:space=\"preserve\">\n    <value>启用服务器拖放排序(需重启)</value>\n  </data>\n  <data name=\"TbAutoRefresh\" xml:space=\"preserve\">\n    <value>自动刷新</value>\n  </data>\n  <data name=\"SpeedtestingSkip\" xml:space=\"preserve\">\n    <value>跳过测试</value>\n  </data>\n  <data name=\"menuEditServer\" xml:space=\"preserve\">\n    <value>编辑服务器 (Ctrl+D)</value>\n  </data>\n  <data name=\"TbSettingsDoubleClick2Activate\" xml:space=\"preserve\">\n    <value>主界面双击设为活动服务器</value>\n  </data>\n  <data name=\"SpeedtestingCompleted\" xml:space=\"preserve\">\n    <value>测试完成</value>\n  </data>\n  <data name=\"TbSettingsDefFingerprint\" xml:space=\"preserve\">\n    <value>默认TLS指纹(fingerprint)</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgent\" xml:space=\"preserve\">\n    <value>用户代理(User-Agent)</value>\n  </data>\n  <data name=\"TbSettingsDefUserAgentTips\" xml:space=\"preserve\">\n    <value>仅对tcp/http、ws协议生效</value>\n  </data>\n  <data name=\"TbSettingsCurrentFontFamily\" xml:space=\"preserve\">\n    <value>当前字体(需重启)</value>\n  </data>\n  <data name=\"TbSettingsCurrentFontFamilyTip\" xml:space=\"preserve\">\n    <value>拷贝字体TTF文件到目录guiFonts，重启设置</value>\n  </data>\n  <data name=\"TbSettingsSocksPortTip\" xml:space=\"preserve\">\n    <value>http端口=socks端口+1</value>\n  </data>\n  <data name=\"TbSettingsStartBootTip\" xml:space=\"preserve\">\n    <value>以管理员权限设置此项，在启动后获得管理员权限</value>\n  </data>\n  <data name=\"TbSettingsFontSize\" xml:space=\"preserve\">\n    <value>字体大小</value>\n  </data>\n  <data name=\"TbSettingsTunModeProxyIP\" xml:space=\"preserve\">\n    <value>代理的IP CIDR，用逗号(,)分隔</value>\n  </data>\n  <data name=\"TbSettingsTunModeProxyProcess\" xml:space=\"preserve\">\n    <value>代理的进程名，用逗号(,)分隔</value>\n  </data>\n  <data name=\"TbSettingsTunModeBypassMode\" xml:space=\"preserve\">\n    <value>绕行模式</value>\n  </data>\n  <data name=\"TbSettingsTunModeBypassModeTip\" xml:space=\"preserve\">\n    <value>启用：路由无匹配则最终代理</value>\n  </data>\n  <data name=\"TbSettingsSpeedTestTimeout\" xml:space=\"preserve\">\n    <value>测速单个超时值</value>\n  </data>\n  <data name=\"TbSettingsSpeedTestUrl\" xml:space=\"preserve\">\n    <value>测速文件地址</value>\n  </data>\n  <data name=\"TbSettingsTunModeDNS\" xml:space=\"preserve\">\n    <value>DNS对象，例如 {\"servers\":[]}</value>\n  </data>\n  <data name=\"menuMoveTo\" xml:space=\"preserve\">\n    <value>移至上下</value>\n  </data>\n  <data name=\"TbPublicKey\" xml:space=\"preserve\">\n    <value>PublicKey</value>\n  </data>\n  <data name=\"TbShortId\" xml:space=\"preserve\">\n    <value>ShortId</value>\n  </data>\n  <data name=\"TbSpiderX\" xml:space=\"preserve\">\n    <value>SpiderX</value>\n  </data>\n  <data name=\"TbSettingsEnableHWA\" xml:space=\"preserve\">\n    <value>启用硬件加速(需重启)</value>\n  </data>\n  <data name=\"SpeedtestingWait\" xml:space=\"preserve\">\n    <value>等待测试中...</value>\n  </data>\n  <data name=\"TipDisplayLog\" xml:space=\"preserve\">\n    <value>当有异常断流时请关闭</value>\n  </data>\n  <data name=\"MsgSkipSubscriptionUpdate\" xml:space=\"preserve\">\n    <value>未启用更新，跳过此订阅</value>\n  </data>\n  <data name=\"menuRebootAsAdmin\" xml:space=\"preserve\">\n    <value>以管理员身份重启</value>\n  </data>\n  <data name=\"LvMoreUrl\" xml:space=\"preserve\">\n    <value>更多地址(url)，用逗号(,)分隔；订阅转换将失效</value>\n  </data>\n  <data name=\"LvAutoUpdateInterval\" xml:space=\"preserve\">\n    <value>自动更新间隔(分钟)</value>\n  </data>\n  <data name=\"TbSettingsLogEnabledToFile\" xml:space=\"preserve\">\n    <value>启用日志存到文件</value>\n  </data>\n  <data name=\"LvConvertTarget\" xml:space=\"preserve\">\n    <value>订阅转换目标类型</value>\n  </data>\n  <data name=\"LvConvertTargetTip\" xml:space=\"preserve\">\n    <value>不需要转换时请留空</value>\n  </data>\n  <data name=\"menuDNSSetting\" xml:space=\"preserve\">\n    <value>DNS设置</value>\n  </data>\n  <data name=\"TbSettingsCoreDnsSingbox\" xml:space=\"preserve\">\n    <value>Sing-box DNS设置</value>\n  </data>\n  <data name=\"TbDnsSingboxObjectDoc\" xml:space=\"preserve\">\n    <value>请填写 DNS JSON 结构，点击查看文档</value>\n  </data>\n  <data name=\"TBSettingDnsImportDefConfig\" xml:space=\"preserve\">\n    <value>点击导入默认DNS配置</value>\n  </data>\n  <data name=\"TbdomainStrategy4Singbox\" xml:space=\"preserve\">\n    <value>Sing-box域名解析策略</value>\n  </data>\n  <data name=\"TbEnableProxy\" xml:space=\"preserve\">\n    <value>Active Proxy</value>\n  </data>\n</root>"
  },
  {
    "path": "v2rayN/v2rayN/Sample/SampleClientConfig",
    "content": "﻿{\n\t\"log\": {\n\t\t\"access\": \"Vaccess.log\",\n\t\t\"error\": \"Verror.log\",\n\t\t\"loglevel\": \"warning\"\n\t},\n\t\"inbounds\": [\n\t\t{\n\t\t\t\"tag\": \"tag1\",\n\t\t\t\"port\": 10808,\n\t\t\t\"protocol\": \"socks\",\n\t\t\t\"listen\": \"127.0.0.1\",\n\t\t\t\"settings\": {\n\t\t\t\t\"auth\": \"noauth\",\n\t\t\t\t\"udp\": true\n\t\t\t},\n\t\t\t\"sniffing\": {\n\t\t\t\t\"enabled\": true,\n\t\t\t\t\"destOverride\": [\n\t\t\t\t\t\"http\",\n\t\t\t\t\t\"tls\"\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"tag\": \"tag2\",\n\t\t\t\"port\": 10809,\n\t\t\t\"protocol\": \"http\",\n\t\t\t\"listen\": \"127.0.0.1\",\n\t\t\t\"settings\": {\n\t\t\t\t\"allowTransparent\": false\n\t\t\t},\n\t\t\t\"sniffing\": {\n\t\t\t\t\"enabled\": true,\n\t\t\t\t\"destOverride\": [\n\t\t\t\t\t\"http\",\n\t\t\t\t\t\"tls\"\n\t\t\t\t]\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"tag\": \"tag3\",\n\t\t\t\"port\": 10809,\n\t\t\t\"protocol\": \"http\",\n\t\t\t\"listen\": \"127.0.0.1\",\n\t\t\t\"settings\": {\n\t\t\t\t\"allowTransparent\": false\n\t\t\t},\n\t\t\t\"sniffing\": {\n\t\t\t\t\"enabled\": true,\n\t\t\t\t\"destOverride\": [\n\t\t\t\t\t\"http\",\n\t\t\t\t\t\"tls\"\n\t\t\t\t]\n\t\t\t}\n\t\t}\n\t],\n\t\"outbounds\": [\n\t\t{\n\t\t\t\"tag\": \"proxy\",\n\t\t\t\"protocol\": \"vmess\",\n\t\t\t\"settings\": {\n\t\t\t\t\"vnext\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"address\": \"v2ray.cool\",\n\t\t\t\t\t\t\"port\": 10086,\n\t\t\t\t\t\t\"users\": [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"id\": \"a3482e88-686a-4a58-8126-99c9df64b7bf\",\n\t\t\t\t\t\t\t\t\"security\": \"auto\"\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t]\n\t\t\t\t\t}\n\t\t\t\t],\n\t\t\t\t\"servers\": [\n\t\t\t\t\t{\n\t\t\t\t\t\t\"address\": \"v2ray.cool\",\n\t\t\t\t\t\t\"method\": \"chacha20\",\n\t\t\t\t\t\t\"ota\": false,\n\t\t\t\t\t\t\"password\": \"123456\",\n\t\t\t\t\t\t\"port\": 10086,\n\t\t\t\t\t\t\"level\": 1\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t},\n\t\t\t\"streamSettings\": {\n\t\t\t\t\"network\": \"tcp\"\n\t\t\t},\n\t\t\t\"mux\": {\n\t\t\t\t\"enabled\": false\n\t\t\t}\n\t\t},\n\t\t{\n\t\t\t\"protocol\": \"freedom\",\n\t\t\t\"settings\": {},\n\t\t\t\"tag\": \"direct\"\n\t\t},\n\t\t{\n\t\t\t\"protocol\": \"blackhole\",\n\t\t\t\"tag\": \"block\",\n\t\t\t\"settings\": {\n\t\t\t\t\"response\": {\n\t\t\t\t\t\"type\": \"http\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t],\n\t\"routing\": {\n\t\t\"domainStrategy\": \"IPIfNonMatch\",\n\t\t\"rules\": [\n\t\t\t{\n\t\t\t\t\"inboundTag\": [ \"api\" ],\n\t\t\t\t\"outboundTag\": \"api\",\n\t\t\t\t\"type\": \"field\"\n\t\t\t}\n\t\t],\n\t\t\"balancers\": []\n\t}\n\t//,\n\t//\"observatory\": {\n\t\t//\"subjectSelector\": [\"balancer\"],\n\t\t//\"probeURL\": \"http://www.google.com/generate_204\",\n\t\t//\"probeInterval\": \"1m\"\n\t//}\n}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/SampleHttprequest",
    "content": "﻿{\"version\":\"1.1\",\"method\":\"GET\",\"path\":[$requestPath$],\"headers\":{\"Host\":[$requestHost$],\"User-Agent\":[$requestUserAgent$],\"Accept-Encoding\":[\"gzip, deflate\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/SampleHttpresponse",
    "content": "﻿{\"version\":\"1.1\",\"status\":\"200\",\"reason\":\"OK\",\"headers\":{\"Content-Type\":[\"application/octet-stream\",\"video/mpeg\"],\"Transfer-Encoding\":[\"chunked\"],\"Connection\":[\"keep-alive\"],\"Pragma\":\"no-cache\"}}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/SampleInbound",
    "content": "﻿{\n\t\"tag\": \"tag1\",\n\t\"port\": 10808,\n\t\"protocol\": \"socks\",\n\t\"listen\": \"127.0.0.1\",\n\t\"settings\": {\n\t\t\"auth\": \"noauth\",\n\t\t\"udp\": true,\n\t\t\"allowTransparent\": false\n\t},\n\t\"sniffing\": {\n\t\t\"enabled\": true,\n\t\t\"destOverride\": [\n\t\t\t\"http\",\n\t\t\t\"tls\"\n\t\t]\n\t}\n} "
  },
  {
    "path": "v2rayN/v2rayN/Sample/SingboxSampleClientConfig",
    "content": "﻿{\n\t\"log\": {\n\t\t\"level\": \"debug\",\n\t\t\"timestamp\": true\n\t},\n\t\"inbounds\": [\n\t\t{\n\t\t\t\"type\": \"socks\",\n\t\t\t\"tag\": \"socks\",\n\t\t\t\"listen\": \"127.0.0.1\",\n\t\t\t\"listen_port\": 10000\n\t\t}\n\t],\n\t\"outbounds\": [\n\t\t{\n\t\t\t\"type\": \"vless\",\n\t\t\t\"tag\": \"proxy\",\n\t\t\t\"server\": \"\",\n\t\t\t\"server_port\": 443\n\t\t},\n\t\t{\n\t\t\t\"type\": \"direct\",\n\t\t\t\"tag\": \"direct\"\n\t\t},\n\t\t{\n\t\t\t\"type\": \"block\",\n\t\t\t\"tag\": \"block\"\n\t\t}\n\t],\n\t\"route\": {\n\t\t\"rules\": []\n\t}\n}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/custom_routing_black",
    "content": "[\n  {\n    \"outboundTag\": \"proxy\",\n    \"domain\": [\n      \"domain:example.com\",\n      \"domain:example2.com\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"port\": \"\",\n    \"outboundTag\": \"block\",\n    \"domain\": [\n      \"geosite:category-ads-all\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"port\": \"\",\n    \"outboundTag\": \"proxy\",\n    \"domain\": [\n      \"tld-!ir\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"port\": \"\",\n    \"outboundTag\": \"proxy\",\n    \"ip\": [\n      \"109.239.140.0/24\",\n      \"149.154.160.0/22\",\n      \"149.154.164.0/22\",\n      \"149.154.168.0/22\",\n      \"149.154.172.0/22\",\n      \"67.198.55.0/24\",\n      \"91.108.12.0/22\",\n      \"91.108.16.0/22\",\n      \"91.108.20.0/22\",\n      \"91.108.20.0/23\",\n      \"91.108.4.0/22\",\n      \"91.108.56.0/22\",\n      \"91.108.56.0/23\",\n      \"91.108.8.0/22\",\n      \"95.161.64.0/20\",\n      \"95.161.84.0/23\",\n      \"2001:67c:4e8::/48\",\n      \"2001:b28:f23c::/48\",\n      \"2001:b28:f23d::/48\",\n      \"2001:b28:f23f::/48\",\n      \"2001:b28:f242::/48\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"port\": \"\",\n    \"outboundTag\": \"proxy\",\n    \"ip\": [\n      \"geoip:facebook\",\n      \"geoip:fastly\",\n      \"geoip:netflix\",\n      \"geoip:telegram\",\n      \"geoip:twitter\",\n      \"geoip:ae\",\n      \"geoip:au\",\n      \"geoip:br\",\n      \"geoip:ca\",\n      \"geoip:de\",\n      \"geoip:dk\",\n      \"geoip:es\",\n      \"geoip:fi\",\n      \"geoip:fr\",\n      \"geoip:gb\",\n      \"geoip:gr\",\n      \"geoip:hk\",\n      \"geoip:id\",\n      \"geoip:il\",\n      \"geoip:in\",\n      \"geoip:iq\",\n      \"geoip:it\",\n      \"geoip:jp\",\n      \"geoip:kr\",\n      \"geoip:mo\",\n      \"geoip:my\",\n      \"geoip:nl\",\n      \"geoip:no\",\n      \"geoip:nz\",\n      \"geoip:ph\",\n      \"geoip:ru\",\n      \"geoip:sa\",\n      \"geoip:sg\",\n      \"geoip:th\",\n      \"geoip:tr\",\n      \"geoip:tw\",\n      \"geoip:us\",\n      \"geoip:vn\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"port\": \"0-65535\",\n    \"outboundTag\": \"direct\"\n  }\n]\n"
  },
  {
    "path": "v2rayN/v2rayN/Sample/custom_routing_global",
    "content": "[\n\t{\n\t\t\"port\": \"0-65535\",\n\t\t\"outboundTag\": \"proxy\"\n\t}\n]"
  },
  {
    "path": "v2rayN/v2rayN/Sample/custom_routing_locked",
    "content": "[\n  {\n    \"domain\": [\n      \"geosite:google\"\n    ],\n    \"outboundTag\": \"proxy\"\n  },\n  {\n    \"outboundTag\": \"direct\",\n    \"domain\": [\n      \"domain:example-example.com\",\n      \"domain:example-example2.com\"\n    ]\n  },\n  {\n    \"outboundTag\": \"block\",\n    \"domain\": [\n      \"geosite:category-ads-all\"\n    ]\n  }\n]"
  },
  {
    "path": "v2rayN/v2rayN/Sample/custom_routing_rules",
    "content": "[{\n\t\t\"remarks\": \"block\",\n\t\t\"outboundTag\": \"block\",\n\t\t\"domain\": [\n\t\t\t\"geosite:category-ads-all\"\n\t\t]\n\t},\n\t{\n\t\t\"remarks\": \"direct\",\n\t\t\"outboundTag\": \"direct\",\n\t\t\"domain\": [\n\t\t\t\"geosite:ir\"\n\t\t]\n\t},\n  {\n    \"remarks\": \"direct\",\n    \"outboundTag\": \"direct\",\n    \"ip\": [\n      \"geoip:private\",\n      \"geoip:ir\"\n    ]\n  },\n\t{\n\t\t\"remarks\": \"proxy\",\n\t\t\"port\": \"0-65535\",\n\t\t\"outboundTag\": \"proxy\"\n\t}\n]"
  },
  {
    "path": "v2rayN/v2rayN/Sample/custom_routing_white",
    "content": "[\n  {\n    \"outboundTag\": \"direct\",\n    \"domain\": [\n      \"domain:example.com\",\n      \"domain:example2.com\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"outboundTag\": \"block\",\n    \"domain\": [\n      \"geosite:category-ads-all\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"outboundTag\": \"direct\",\n    \"domain\": [\n      \"geosite:private\",\n      \"geosite:apple@cn\",\n      \"geosite:google@cn\",\n      \"geosite:tld-cn\",\n      \"tld-ir\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"outboundTag\": \"proxy\",\n    \"domain\": [\n      \"geoip:!ir\"\n    ]\n  },\n  {\n    \"type\": \"field\",\n    \"outboundTag\": \"direct\",\n    \"ip\": [\n      \"geoip:private\",\n      \"geoip:cn\",\n      \"geoip:ir\"\n    ],\n    \"domain\": []\n  },\n  {\n    \"type\": \"field\",\n    \"port\": \"0-65535\",\n    \"outboundTag\": \"proxy\"\n  }\n]\n"
  },
  {
    "path": "v2rayN/v2rayN/Sample/dns_singbox_normal",
    "content": "{\n  \"servers\": [\n    {\n      \"tag\": \"remote\",\n      \"address\": \"tcp://8.8.8.8\",\n      \"detour\": \"proxy\"\n    },\n    {\n      \"tag\": \"local\",\n      \"address\": \"223.5.5.5\",\n      \"detour\": \"direct\"\n    },\n    {\n      \"tag\": \"block\",\n      \"address\": \"rcode://success\"\n    }\n  ],\n  \"rules\": [\n    {\n      \"geosite\": [\n        \"cn\"\n      ],\n      \"server\": \"local\"\n    },\n    {\n      \"geosite\": [\n        \"category-ads-all\"\n      ],\n      \"server\": \"block\"\n    }\n  ]\n}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/dns_v2ray_normal",
    "content": "{\n  \"hosts\": {\n    \"dns.google\": \"8.8.8.8\",\n    \"proxy.example.com\": \"127.0.0.1\"\n  },\n  \"servers\": [\n    {\n      \"address\": \"223.5.5.5\",\n      \"domains\": [\n        \"geosite:cn\"\n      ],\n      \"expectIPs\": [\n        \"geoip:cn\"\n      ]\n    },\n    \"1.1.1.1\",\n    \"8.8.8.8\",\n    \"https://dns.google/dns-query\"\n  ]\n}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/tun_singbox",
    "content": "{\n  \"log\": {\n    \"disabled\": $log_disabled$,\n    \"level\": \"debug\",\n    $log_output$\n    \"timestamp\": true\n  },\n  \"dns\": $dns_object$ ,\n  \"inbounds\": [\n    {\n      \"type\": \"tun\",\n      \"tag\": \"tun-in\",\n      \"interface_name\": \"singbox_tun\",\n      \"inet4_address\": \"172.19.0.1/30\",\n\n      \"mtu\": $mtu$,\n      \"auto_route\": true,\n      \"strict_route\": $strict_route$,\n      \"stack\": \"$stack$\",\n      \"sniff\": true\n    }\n  ],\n  \"outbounds\": [\n    {\n      \"type\": \"socks\",\n      \"tag\": \"proxy\",\n      \"udp_fragment\": true,\n      \"server\": \"127.0.0.1\",\n      \"server_port\": $socksPort$\n    },\n    {\n      \"type\": \"block\",\n      \"tag\": \"block\"\n    },\n    {\n      \"type\": \"direct\",\n      \"tag\": \"direct\"\n    },\n    {\n      \"type\": \"dns\",\n      \"tag\": \"dns_out\"\n    }\n  ],\n  \"route\": {\n    \"auto_detect_interface\": true,\n    \"rules\": [\n      {\n        \"inbound\": \"dns_in\",\n        \"outbound\": \"dns_out\"\n      },\n      {\n        \"protocol\": \"dns\",\n        \"outbound\": \"dns_out\"\n      },\n      {\n        \"network\": \"udp\",\n        \"port\": [\n          135,\n          137,\n          138,\n          139,\n          5353\n        ],\n        \"outbound\": \"block\"\n      },\n      {\n        \"ip_cidr\": [\n          \"224.0.0.0/3\",\n          \"ff00::/8\"\n        ],\n        \"outbound\": \"block\"\n      },\n      {\n        \"source_ip_cidr\": [\n          \"224.0.0.0/3\",\n          \"ff00::/8\"\n        ],\n        \"outbound\": \"block\"\n      },\n      {\n        \"port\": 53,\n        \"process_name\": [ $dnsProcessName$],\n        \"outbound\": \"dns_out\"\n      },\n      {\n        \"process_name\": [ $directProcessName$],\n        \"outbound\": \"direct\"\n      }\n      $ruleDirectIPs$\n      $ruleDirectProcess$\n      $ruleProxyIPs$\n      $ruleProxyProcess$\n      $ruleFinally$\n    ]\n  }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/tun_singbox_dns",
    "content": "{\n  \"servers\": [\n    {\n      \"tag\": \"remote\",\n      \"address\": \"tcp://8.8.8.8\",\n      \"detour\": \"proxy\"\n    },\n    {\n      \"tag\": \"local\",\n      \"address\": \"223.5.5.5\",\n      \"detour\": \"direct\"\n    },\n    {\n      \"tag\": \"block\",\n      \"address\": \"rcode://success\"\n    }\n  ],\n  \"rules\": [\n    {\n      \"geosite\": [\n        \"cn\"\n      ],\n      \"server\": \"local\",\n      \"disable_cache\": true\n    },\n    {\n      \"geosite\": [\n        \"category-ads-all\"\n      ],\n      \"server\": \"block\",\n      \"disable_cache\": true\n    }\n  ],\n  \"strategy\": \"ipv4_only\"\n}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/tun_singbox_inbound",
    "content": "{\n   \"type\":\"tun\",\n   \"tag\":\"tun-in\",\n   \"interface_name\":\"singbox_tun\",\n   \"inet4_address\":\"172.19.0.1/30\",\n   \"mtu\":9000,\n   \"auto_route\":true,\n   \"strict_route\":false,\n   \"stack\":\"system\",\n   \"sniff\":true\n}"
  },
  {
    "path": "v2rayN/v2rayN/Sample/tun_singbox_rules",
    "content": "[\n  {\n    \"inbound\": [ \"dns_in\" ],\n    \"outbound\": \"dns_out\"\n  },\n  {\n    \"protocol\": [ \"dns\" ],\n    \"outbound\": \"dns_out\"\n  },\n  {\n    \"network\": \"udp\",\n    \"port\": [\n      135,\n      137,\n      138,\n      139,\n      5353\n    ],\n    \"outbound\": \"block\"\n  },\n  {\n    \"ip_cidr\": [\n      \"224.0.0.0/3\",\n      \"ff00::/8\"\n    ],\n    \"outbound\": \"block\"\n  },\n  {\n    \"source_ip_cidr\": [\n      \"224.0.0.0/3\",\n      \"ff00::/8\"\n    ],\n    \"outbound\": \"block\"\n  }\n]"
  },
  {
    "path": "v2rayN/v2rayN/Tool/DeepLinking.cs",
    "content": "﻿using Microsoft.Win32;\nusing v2rayN.Handler;\n\nnamespace v2rayN.Tool\n{\n    public class DeepLinking\n    {\n        const string FriendlyName = \"HiddifyN\";\n        const string SchemeSeperator = \"://\";\n        readonly static string applicationLocation = Utils.GetExePath();\n        public static void RegisterSchemes()\n        {\n\n            foreach (var scheme in System.Enum.GetNames(typeof(Scheme)))\n            {\n                // If scheme registered we just skip it\n                if (CheckSchemeRegistered(scheme))\n                {\n                    continue;\n                }\n\n                using (var key = Registry.CurrentUser.CreateSubKey(\"SOFTWARE\\\\Classes\\\\\" + scheme))\n                {\n                    // Replace typeof(App) by the class that contains the Main method or any class located in the project that produces the exe.\n                    // or replace typeof(App).Assembly.Location by anything that gives the full path to the exe\n\n                    key.SetValue(\"\", \"URL:\" + FriendlyName);\n                    key.SetValue(\"URL Protocol\", \"\");\n\n                    using (var defaultIcon = key.CreateSubKey(\"DefaultIcon\"))\n                    {\n                        defaultIcon.SetValue(\"\", applicationLocation + \",1\");\n                    }\n\n                    using (var commandKey = key.CreateSubKey(@\"shell\\open\\command\"))\n                    {\n                        commandKey.SetValue(\"\", \"\\\"\" + applicationLocation + \"\\\" \\\"%1\\\"\");\n                    }\n                }\n\n            }\n        }\n\n        public static bool CheckSchemeRegistered(string scheme)\n        {\n            using (var key = Registry.CurrentUser.CreateSubKey(\"SOFTWARE\\\\Classes\\\\\" + scheme))\n            {\n                if (key?.GetValue(\"\")?.ToString() == \"URL:\" + FriendlyName)\n                {\n                    using (var defaultIcon = key.OpenSubKey(\"DefaultIcon\"))\n                    {\n                        if (defaultIcon?.GetValue(\"\").ToString() == applicationLocation + \",1\")\n                        {\n                            using (var commandKey = key.OpenSubKey(@\"shell\\open\\command\"))\n                            {\n                                if (commandKey?.GetValue(\"\").ToString() == \"\\\"\" + applicationLocation + \"\\\" \\\"%1\\\"\")\n                                {\n                                    return true;\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            return false;\n        }\n\n        public static (bool, string?) IsUriForProgram(string uri)\n        {\n            uri = uri.ToLower();\n\n            foreach (var scheme in System.Enum.GetNames(typeof(Scheme)))\n            {\n                if (uri.StartsWith(scheme + SchemeSeperator))\n                {\n                    return (true, scheme);\n                }\n\n            }\n            return (false, null);\n        }\n        private static (Protocol?, string?) ParseProtocol(string uri)\n        {\n            Protocol protocol = new Protocol();\n            string err = null;\n\n            // Parse Vless Uri\n            if (uri.StartsWith(\"vless\" + SchemeSeperator))\n            {\n                protocol.Uri = uri;\n                protocol.Scheme = Scheme.vless;\n            }\n            // Parse Vmess Uri\n            else if (uri.StartsWith(\"vmess\" + SchemeSeperator))\n            {\n                protocol.Uri = uri;\n                protocol.Scheme = Scheme.vmees;\n            }\n            // Parse Shadowsocks(ss) Uri\n            else if (uri.StartsWith(\"ss\" + SchemeSeperator))\n            {\n                protocol.Uri = uri;\n                protocol.Scheme = Scheme.ss;\n            }\n            // Parse Trojan Uri\n            else if (uri.StartsWith(\"trojan\" + SchemeSeperator))\n            {\n                protocol.Uri = uri;\n                protocol.Scheme = Scheme.trojan;\n            }\n            // Handle Unexcepted Uri\n            else\n            {\n                return (res: null, err: $\"The {uri} is not supported in deep linking\");\n            }\n\n            return (protocol, err);\n        }\n\n        private static (Subscription?, string?) ParseSubscription(string uri)\n        {\n            // Valid uri sample: hiddify://install-sub?url=domain.com/path/clash.yml&name=sub_name\n            if (!uri.Contains(\"url=\"))\n            {\n                return (null, \"Invalid uri\");\n            }\n\n            // Extract url\n            //var url Utils.ExtractUrlParameterFromUri(uri);\n           \n            #region Download sub link data\n            //// Download url data\n            //string data = \"\";\n            //string err = \"\";\n            //var task = Task.Run(async () =>\n            //{\n            //    try\n            //    {\n            //        var downloader = new DownloadHandle();\n\n            //        // Download through proxy\n            //        string url_res = await downloader.TryDownloadString(subscription.Url, true, \"\");\n            //        if (Utils.IsNullOrEmpty(url_res.Trim()))\n            //        {\n            //            // Download without proxy\n            //            url_res = await downloader.TryDownloadString(subscription.Url, false, \"\");\n            //        }\n            //        data = url_res;\n            //    }\n            //    catch (Exception e)\n            //    {\n            //        err = e.Message;\n            //    }\n\n            //});\n            //task.Wait();\n\n            //if (err != \"\")\n            //{\n            //    return (null, err);\n            //}\n            //if (Utils.IsNullOrEmpty(data.Trim()))\n            //{\n            //    return (null, \"Error occurred getting url data\");\n            //}\n            //subscription.Data = data;\n            #endregion\n\n            Subscription subscription = new Subscription();\n            subscription.Url = Utils.ChangeHiddifySubDeeplinkToNormalSubUri(uri);\n            return (subscription, \"\");\n        }\n        private static bool IsUriSub(string uri)\n        {\n            if (uri.StartsWith(\"hiddify://install-sub\"))\n            {\n                return true;\n            }\n            return false;\n        }\n        public static (ParseResult? res, string? err) ParseUri(string uri)\n        {\n\n            ParseResult result = new ParseResult();\n            string err = null;\n            // If the uri is a subscription link we should download it and then add it\n            // If the uri is just a protocol link, we have nothing much to do\n            if (IsUriSub(uri))\n            {\n                (result.subscription,err) = ParseSubscription(uri);\n            }\n            else\n            {\n                (result.protocol,err) = ParseProtocol(uri);\n\n            }\n            if (err != null && err != \"\")\n            {\n                return (null, err);\n            }\n            // Return result (error field is null)\n            return (result, null);\n\n        }\n    }\n    public class ParseResult\n    {\n        public Protocol? protocol { get; set; }\n\n        public Subscription? subscription { get; set; }\n    }\n\n    public class Protocol\n    {\n        // It will be extracted when it's getting add\n        //public string? Name { get; set; }\n        public string Uri { get; set; }\n        // It's useless for now\n        public Scheme Scheme { get; set; }\n    }\n\n\n    public class Subscription\n    {\n        // Name of the sub will be extracted when it's getting add\n        //public string Name { get; set; }\n        public string Url { get; set; }\n        // We don't download sub link data, we just imoprt it and then update the sub\n        //public string Data { get; set; }\n    }\n\n\n    public enum Scheme\n    {\n        // Clash will be regarded as a subscription\n        //clash\n        vless,\n        vmees,\n        ss,\n        trojan,\n        // The program main scheme\n        hiddify,\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Tool/FileManager.cs",
    "content": "﻿using System.IO;\nusing System.IO.Compression;\nusing System.Text;\n\nnamespace v2rayN.Tool\n{\n    public static class FileManager\n    {\n        public static bool ByteArrayToFile(string fileName, byte[] content)\n        {\n            try\n            {\n                File.WriteAllBytes(fileName, content);\n                return true;\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n            return false;\n        }\n\n        public static void UncompressFile(string fileName, byte[] content)\n        {\n            try\n            {\n                using FileStream fs = File.Create(fileName);\n                using GZipStream input = new(new MemoryStream(content), CompressionMode.Decompress, false);\n                input.CopyTo(fs);\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        public static string NonExclusiveReadAllText(string path)\n        {\n            return NonExclusiveReadAllText(path, Encoding.Default);\n        }\n\n        public static string NonExclusiveReadAllText(string path, Encoding encoding)\n        {\n            try\n            {\n                using FileStream fs = new(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);\n                using StreamReader sr = new(fs, encoding);\n                return sr.ReadToEnd();\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                throw;\n            }\n        }\n\n        public static bool ZipExtractToFile(string fileName, string toPath, string ignoredName)\n        {\n            try\n            {\n                using ZipArchive archive = ZipFile.OpenRead(fileName);\n                foreach (ZipArchiveEntry entry in archive.Entries)\n                {\n                    if (entry.Length == 0)\n                    {\n                        continue;\n                    }\n                    try\n                    {\n                        if (!Utils.IsNullOrEmpty(ignoredName) && entry.Name.Contains(ignoredName))\n                        {\n                            continue;\n                        }\n                        entry.ExtractToFile(Path.Combine(toPath, entry.Name), true);\n                    }\n                    catch (IOException ex)\n                    {\n                        Utils.SaveLog(ex.Message, ex);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n                return false;\n            }\n            return true;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Tool/Job.cs",
    "content": "﻿using System.Diagnostics;\nusing System.Runtime.InteropServices;\n\nnamespace v2rayN\n{\n    /*\n     * See:\n     * http://stackoverflow.com/questions/6266820/working-example-of-createjobobject-setinformationjobobject-pinvoke-in-net\n     */\n\n    public class Job : IDisposable\n    {\n        private IntPtr handle = IntPtr.Zero;\n\n        public Job()\n        {\n            handle = CreateJobObject(IntPtr.Zero, null);\n            IntPtr extendedInfoPtr = IntPtr.Zero;\n            JOBOBJECT_BASIC_LIMIT_INFORMATION info = new()\n            {\n                LimitFlags = 0x2000\n            };\n\n            JOBOBJECT_EXTENDED_LIMIT_INFORMATION extendedInfo = new()\n            {\n                BasicLimitInformation = info\n            };\n\n            try\n            {\n                int length = Marshal.SizeOf(typeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION));\n                extendedInfoPtr = Marshal.AllocHGlobal(length);\n                Marshal.StructureToPtr(extendedInfo, extendedInfoPtr, false);\n\n                if (!SetInformationJobObject(handle, JobObjectInfoType.ExtendedLimitInformation, extendedInfoPtr,\n                        (uint)length))\n                    throw new Exception(string.Format(\"Unable to set information.  Error: {0}\",\n                        Marshal.GetLastWin32Error()));\n            }\n            finally\n            {\n                if (extendedInfoPtr != IntPtr.Zero)\n                {\n                    Marshal.FreeHGlobal(extendedInfoPtr);\n                }\n            }\n        }\n\n        public bool AddProcess(IntPtr processHandle)\n        {\n            bool succ = AssignProcessToJobObject(handle, processHandle);\n\n            if (!succ)\n            {\n                Utils.SaveLog(\"Failed to call AssignProcessToJobObject! GetLastError=\" + Marshal.GetLastWin32Error());\n            }\n\n            return succ;\n        }\n\n        public bool AddProcess(int processId)\n        {\n            return AddProcess(Process.GetProcessById(processId).Handle);\n        }\n\n        #region IDisposable\n\n        private bool disposed;\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) return;\n            disposed = true;\n\n            if (disposing)\n            {\n                // no managed objects to free\n            }\n\n            if (handle != IntPtr.Zero)\n            {\n                CloseHandle(handle);\n                handle = IntPtr.Zero;\n            }\n        }\n\n        ~Job()\n        {\n            Dispose(false);\n        }\n\n        #endregion IDisposable\n\n        #region Interop\n\n        [DllImport(\"kernel32.dll\", CharSet = CharSet.Unicode)]\n        private static extern IntPtr CreateJobObject(IntPtr a, string? lpName);\n\n        [DllImport(\"kernel32.dll\", SetLastError = true)]\n        private static extern bool SetInformationJobObject(IntPtr hJob, JobObjectInfoType infoType, IntPtr lpJobObjectInfo, UInt32 cbJobObjectInfoLength);\n\n        [DllImport(\"kernel32.dll\", SetLastError = true)]\n        private static extern bool AssignProcessToJobObject(IntPtr job, IntPtr process);\n\n        [DllImport(\"kernel32.dll\", SetLastError = true)]\n        [return: MarshalAs(UnmanagedType.Bool)]\n        private static extern bool CloseHandle(IntPtr hObject);\n\n        #endregion Interop\n    }\n\n    #region Helper classes\n\n    [StructLayout(LayoutKind.Sequential)]\n    internal struct IO_COUNTERS\n    {\n        public UInt64 ReadOperationCount;\n        public UInt64 WriteOperationCount;\n        public UInt64 OtherOperationCount;\n        public UInt64 ReadTransferCount;\n        public UInt64 WriteTransferCount;\n        public UInt64 OtherTransferCount;\n    }\n\n    [StructLayout(LayoutKind.Sequential)]\n    internal struct JOBOBJECT_BASIC_LIMIT_INFORMATION\n    {\n        public Int64 PerProcessUserTimeLimit;\n        public Int64 PerJobUserTimeLimit;\n        public UInt32 LimitFlags;\n        public UIntPtr MinimumWorkingSetSize;\n        public UIntPtr MaximumWorkingSetSize;\n        public UInt32 ActiveProcessLimit;\n        public UIntPtr Affinity;\n        public UInt32 PriorityClass;\n        public UInt32 SchedulingClass;\n    }\n\n    [StructLayout(LayoutKind.Sequential)]\n    public struct SECURITY_ATTRIBUTES\n    {\n        public UInt32 nLength;\n        public IntPtr lpSecurityDescriptor;\n        public Int32 bInheritHandle;\n    }\n\n    [StructLayout(LayoutKind.Sequential)]\n    internal struct JOBOBJECT_EXTENDED_LIMIT_INFORMATION\n    {\n        public JOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimitInformation;\n        public IO_COUNTERS IoInfo;\n        public UIntPtr ProcessMemoryLimit;\n        public UIntPtr JobMemoryLimit;\n        public UIntPtr PeakProcessMemoryUsed;\n        public UIntPtr PeakJobMemoryUsed;\n    }\n\n    public enum JobObjectInfoType\n    {\n        AssociateCompletionPortInformation = 7,\n        BasicLimitInformation = 2,\n        BasicUIRestrictions = 4,\n        EndOfJobTimeInformation = 6,\n        ExtendedLimitInformation = 9,\n        SecurityLimitInformation = 5,\n        GroupInformation = 11\n    }\n\n    #endregion Helper classes\n}"
  },
  {
    "path": "v2rayN/v2rayN/Tool/Logging.cs",
    "content": "﻿using NLog;\nusing NLog.Config;\nusing NLog.Targets;\nusing System.IO;\n\nnamespace v2rayN.Tool\n{\n    public class Logging\n    {\n        public static void Setup()\n        {\n            LoggingConfiguration config = new();\n            FileTarget fileTarget = new();\n            config.AddTarget(\"file\", fileTarget);\n            fileTarget.Layout = \"${longdate}-${level:uppercase=true} ${message}\";\n            fileTarget.FileName = Utils.GetLogPath(\"${shortdate}.txt\");\n            config.LoggingRules.Add(new LoggingRule(\"*\", LogLevel.Debug, fileTarget));\n            LogManager.Configuration = config;\n        }\n\n        public static void LoggingEnabled(bool enable)\n        {\n            if (!enable)\n            {\n                LogManager.SuspendLogging();\n            }\n        }\n\n        public static void ClearLogs()\n        {\n            Task.Run(() =>\n            {\n                try\n                {\n                    var now = DateTime.Now.AddMonths(-1);\n                    var dir = Utils.GetLogPath();\n                    var files = Directory.GetFiles(dir, \"*.txt\");\n                    foreach (var filePath in files)\n                    {\n                        var file = new FileInfo(filePath);\n                        if (file.CreationTime < now)\n                        {\n                            try\n                            {\n                                file.Delete();\n                            }\n                            catch { }\n                        }\n                    }\n                }\n                catch { }\n            });\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Tool/QueryableExtension.cs",
    "content": "﻿using System.Linq.Expressions;\nusing System.Reflection;\n\nnamespace v2rayN.Tool\n{\n    public static class QueryableExtension\n    {\n        public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> query, string propertyName)\n        {\n            return _OrderBy<T>(query, propertyName, false);\n        }\n\n        public static IOrderedQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string propertyName)\n        {\n            return _OrderBy<T>(query, propertyName, true);\n        }\n\n        private static IOrderedQueryable<T> _OrderBy<T>(IQueryable<T> query, string propertyName, bool isDesc)\n        {\n            string methodname = (isDesc) ? \"OrderByDescendingInternal\" : \"OrderByInternal\";\n\n            var memberProp = typeof(T).GetProperty(propertyName);\n\n            var method = typeof(QueryableExtension).GetMethod(methodname)\n                                       .MakeGenericMethod(typeof(T), memberProp.PropertyType);\n\n            return (IOrderedQueryable<T>)method.Invoke(null, new object[] { query, memberProp });\n        }\n\n        public static IOrderedQueryable<T> OrderByInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)\n        {//public\n            return query.OrderBy(_GetLamba<T, TProp>(memberProperty));\n        }\n\n        public static IOrderedQueryable<T> OrderByDescendingInternal<T, TProp>(IQueryable<T> query, PropertyInfo memberProperty)\n        {//public\n            return query.OrderByDescending(_GetLamba<T, TProp>(memberProperty));\n        }\n\n        private static Expression<Func<T, TProp>> _GetLamba<T, TProp>(PropertyInfo memberProperty)\n        {\n            if (memberProperty.PropertyType != typeof(TProp)) throw new Exception();\n\n            var thisArg = Expression.Parameter(typeof(T));\n            var lamba = Expression.Lambda<Func<T, TProp>>(Expression.Property(thisArg, memberProperty), thisArg);\n\n            return lamba;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Tool/TestSpeed.cs",
    "content": "﻿using v2rayN;\nusing Newtonsoft;\nusing System.Diagnostics;\nusing Newtonsoft.Json.Linq;\nusing System.Net;\nusing Newtonsoft.Json;\nusing System.Windows.Navigation;\n\nnamespace HiddifyN.Tool\n{\n    public class TestSpeed\n    {\n        private string _appHttpProxy;\n        public TestSpeed()\n        {\n            WebProxy p = (WebProxy)Utils.GetAppProxyAddress();\n            _appHttpProxy = p.Address.OriginalString;\n        }\n\n        public double? UploadSpeed(bool withProxy = true)\n        {\n            var sInfo = new ProcessStartInfo();\n            var extra = withProxy ? $\"--http-proxy={_appHttpProxy}\" : \"\";\n            sInfo = new ProcessStartInfo()\n            {\n                FileName = Global.SpeedTestProgramExePath,\n                Arguments = $\"--no-download --no-icmp --json {extra}\",\n                UseShellExecute = false,\n                RedirectStandardOutput = true,\n                RedirectStandardError = true,\n                CreateNoWindow = true,\n            };\n            \n\n            // Start speed tester program and get its output or error and handle it\n            var (stdout, stderr) = Utils.StartProcess(sInfo);\n            if (stdout == null)\n            {\n                return null;\n            }\n            // Parse json result\n            dynamic testerResult = JObject.Parse(ConvertJsonListToObject(stdout.Trim()));\n\n            // Get download speed as Mbps\n            double uploadSpeed = testerResult.upload;\n\n            return uploadSpeed;\n\n        }\n        public double? DownloadSpeed(bool withProxy = true)\n        {\n            var sInfo = new ProcessStartInfo();\n            var extra = withProxy ? $\"--http-proxy={_appHttpProxy}\" : \"\";\n            sInfo = new ProcessStartInfo()\n            {\n                FileName = Global.SpeedTestProgramExePath,\n                Arguments = $\"--no-upload --no-icmp --json {extra}\",\n                UseShellExecute = false,\n                RedirectStandardOutput = true,\n                RedirectStandardError = true,\n                CreateNoWindow = true,\n            };\n            \n\n            // Start speed tester program and get its output or error and handle it\n            var (stdout, stderr) = Utils.StartProcess(sInfo);\n            if (stdout == null)\n            {\n                return null;\n            }\n            // Parse json result\n            dynamic testerResult = JObject.Parse(ConvertJsonListToObject(stdout.Trim()));\n\n            // Get download speed as Mbps\n            double downloadSpeed = testerResult.download;\n\n            return downloadSpeed;\n        }\n\n        private string ConvertJsonListToObject(string j)\n        {\n            return j.Remove(j.Length- 1,1).Remove(0,1).Trim();\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Tool/UI.cs",
    "content": "﻿using System.Windows;\n\nnamespace v2rayN\n{\n    internal class UI\n    {\n        private static readonly string caption = \"HiddifyN\";\n\n        public static void Show(string msg)\n        {\n            MessageBox.Show(msg, caption, MessageBoxButton.OK, MessageBoxImage.Information, MessageBoxResult.OK);\n        }\n\n        public static void ShowWarning(string msg)\n        {\n            MessageBox.Show(msg, caption, MessageBoxButton.OK, MessageBoxImage.Warning, MessageBoxResult.OK);\n        }\n        public static void ShowError(string msg)\n        {\n            MessageBox.Show(msg, caption, MessageBoxButton.OK, MessageBoxImage.Error);\n        }\n\n        public static MessageBoxResult ShowYesNo(string msg)\n        {\n            return MessageBox.Show(msg, caption, MessageBoxButton.YesNo, MessageBoxImage.Question);\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Tool/Utils.cs",
    "content": "﻿using Downloader;\nusing Microsoft.Win32;\nusing Microsoft.Win32.TaskScheduler;\nusing Newtonsoft.Json;\nusing Newtonsoft.Json.Linq;\nusing NLog;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.Drawing;\nusing System.IO;\nusing System.IO.Compression;\nusing System.Net;\nusing System.Net.Http;\nusing System.Net.Http.Headers;\nusing System.Net.NetworkInformation;\nusing System.Net.Sockets;\nusing System.Printing.IndexedProperties;\nusing System.Reflection;\nusing System.Runtime.InteropServices;\nusing System.Runtime.Serialization.Formatters.Binary;\nusing System.Security.Cryptography;\nusing System.Security.Policy;\nusing System.Security.Principal;\nusing System.Text;\nusing System.Text.RegularExpressions;\nusing System.Web;\nusing System.Windows;\nusing System.Windows.Interop;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Navigation;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Tool;\nusing ZXing;\nusing ZXing.Common;\nusing ZXing.QrCode;\nusing ZXing.Windows.Compatibility;\n\nusing System.Net.Mail;\nusing System.Windows.Data;\nusing System.Globalization;\n\nnamespace v2rayN\n{\n    internal class Utils\n    {\n        #region 资源Json操作\n\n        /// <summary>\n        /// 获取嵌入文本资源\n        /// </summary>\n        /// <param name=\"res\"></param>\n        /// <returns></returns>\n        public static string GetEmbedText(string res)\n        {\n            string result = string.Empty;\n\n            try\n            {\n                Assembly assembly = Assembly.GetExecutingAssembly();\n                using Stream? stream = assembly.GetManifestResourceStream(res);\n                ArgumentNullException.ThrowIfNull(stream);\n                using StreamReader reader = new(stream);\n                result = reader.ReadToEnd();\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return result;\n        }\n\n        /// <summary>\n        /// 取得存储资源\n        /// </summary>\n        /// <returns></returns>\n        public static string? LoadResource(string res)\n        {\n            try\n            {\n                if (!File.Exists(res)) return null;\n                return File.ReadAllText(res);\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return null;\n        }\n\n        /// <summary>\n        /// 反序列化成对象\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"strJson\"></param>\n        /// <returns></returns>\n        public static T? FromJson<T>(string? strJson)\n        {\n            try\n            {\n                if (string.IsNullOrEmpty(strJson))\n                {\n                    return default;\n                }\n                return JsonConvert.DeserializeObject<T>(strJson);\n            }\n            catch\n            {\n                return default;\n            }\n        }\n\n        /// <summary>\n        /// 序列化成Json\n        /// </summary>\n        /// <param name=\"obj\"></param>\n        /// <returns></returns>\n        public static string ToJson(object? obj, bool indented = true)\n        {\n            string result = string.Empty;\n            try\n            {\n                if (obj == null)\n                {\n                    return result;\n                }\n                if (indented)\n                {\n                    result = JsonConvert.SerializeObject(obj,\n                                           Formatting.Indented,\n                                           new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });\n                }\n                else\n                {\n                    result = JsonConvert.SerializeObject(obj, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return result;\n        }\n\n        /// <summary>\n        /// 保存成json文件\n        /// </summary>\n        /// <param name=\"obj\"></param>\n        /// <param name=\"filePath\"></param>\n        /// <returns></returns>\n        public static int ToJsonFile(object? obj, string filePath, bool nullValue = true)\n        {\n            int result;\n            try\n            {\n                using StreamWriter file = File.CreateText(filePath);\n                JsonSerializer serializer;\n                if (nullValue)\n                {\n                    serializer = new JsonSerializer() { Formatting = Formatting.Indented };\n                }\n                else\n                {\n                    serializer = new JsonSerializer() { Formatting = Formatting.Indented, NullValueHandling = NullValueHandling.Ignore };\n                }\n\n                serializer.Serialize(file, obj);\n                result = 0;\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n                result = -1;\n            }\n            return result;\n        }\n\n        public static JObject? ParseJson(string strJson)\n        {\n            try\n            {\n                return JObject.Parse(strJson);\n            }\n            catch (Exception ex)\n            {\n                //SaveLog(ex.Message, ex);\n                return null;\n            }\n        }\n\n        #endregion 资源Json操作\n\n        #region 转换函数\n\n        /// <summary>\n        /// List<string>转逗号分隔的字符串\n        /// </summary>\n        /// <param name=\"lst\"></param>\n        /// <returns></returns>\n        public static string List2String(List<string> lst, bool wrap = false)\n        {\n            try\n            {\n                if (lst == null)\n                {\n                    return string.Empty;\n                }\n                if (wrap)\n                {\n                    return string.Join(\",\" + Environment.NewLine, lst);\n                }\n                else\n                {\n                    return string.Join(\",\", lst);\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n                return string.Empty;\n            }\n        }\n\n        /// <summary>\n        /// 逗号分隔的字符串,转List<string>\n        /// </summary>\n        /// <param name=\"str\"></param>\n        /// <returns></returns>\n        public static List<string> String2List(string str)\n        {\n            try\n            {\n                str = str.Replace(Environment.NewLine, \"\");\n                return new List<string>(str.Split(',', StringSplitOptions.RemoveEmptyEntries));\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n                return new List<string>();\n            }\n        }\n\n        /// <summary>\n        /// 逗号分隔的字符串,先排序后转List<string>\n        /// </summary>\n        /// <param name=\"str\"></param>\n        /// <returns></returns>\n        public static List<string> String2ListSorted(string str)\n        {\n            try\n            {\n                str = str.Replace(Environment.NewLine, \"\");\n                List<string> list = new(str.Split(',', StringSplitOptions.RemoveEmptyEntries));\n                list.Sort();\n                return list;\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n                return new List<string>();\n            }\n        }\n\n        /// <summary>\n        /// Base64编码\n        /// </summary>\n        /// <param name=\"plainText\"></param>\n        /// <returns></returns>\n        public static string Base64Encode(string plainText)\n        {\n            try\n            {\n                byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);\n                return Convert.ToBase64String(plainTextBytes);\n            }\n            catch (Exception ex)\n            {\n                SaveLog(\"Base64Encode\", ex);\n                return string.Empty;\n            }\n        }\n\n        /// <summary>\n        /// Base64解码\n        /// </summary>\n        /// <param name=\"plainText\"></param>\n        /// <returns></returns>\n        public static string Base64Decode(string plainText)\n        {\n            try\n            {\n                plainText = plainText.TrimEx()\n                  .Replace(Environment.NewLine, \"\")\n                  .Replace(\"\\n\", \"\")\n                  .Replace(\"\\r\", \"\")\n                  .Replace('_', '/')\n                  .Replace('-', '+')\n                  .Replace(\" \", \"\");\n\n                if (plainText.Length % 4 > 0)\n                {\n                    plainText = plainText.PadRight(plainText.Length + 4 - plainText.Length % 4, '=');\n                }\n\n                byte[] data = Convert.FromBase64String(plainText);\n                return Encoding.UTF8.GetString(data);\n            }\n            catch (Exception ex)\n            {\n                SaveLog(\"Base64Decode\", ex);\n                return string.Empty;\n            }\n        }\n\n        /// <summary>\n        /// 转Int\n        /// </summary>\n        /// <param name=\"obj\"></param>\n        /// <returns></returns>\n        public static int ToInt(object obj)\n        {\n            try\n            {\n                return Convert.ToInt32(obj);\n            }\n            catch (Exception ex)\n            {\n                //SaveLog(ex.Message, ex);\n                return 0;\n            }\n        }\n\n        public static bool ToBool(object obj)\n        {\n            try\n            {\n                return Convert.ToBoolean(obj);\n            }\n            catch (Exception ex)\n            {\n                //SaveLog(ex.Message, ex);\n                return false;\n            }\n        }\n\n        public static string ToString(object obj)\n        {\n            try\n            {\n                return obj?.ToString() ?? string.Empty;\n            }\n            catch (Exception ex)\n            {\n                //SaveLog(ex.Message, ex);\n                return string.Empty;\n            }\n        }\n\n        /// <summary>\n        /// byte 转成 有两位小数点的 方便阅读的数据\n        ///     比如 2.50 MB\n        /// </summary>\n        /// <param name=\"amount\">bytes</param>\n        /// <param name=\"result\">转换之后的数据</param>\n        /// <param name=\"unit\">单位</param>\n        public static void ToHumanReadable(long amount, out double result, out string unit)\n        {\n            uint factor = 1024u;\n            //long KBs = amount / factor;\n            long KBs = amount;\n            if (KBs > 0)\n            {\n                // multi KB\n                long MBs = KBs / factor;\n                if (MBs > 0)\n                {\n                    // multi MB\n                    long GBs = MBs / factor;\n                    if (GBs > 0)\n                    {\n                        // multi GB\n                        long TBs = GBs / factor;\n                        if (TBs > 0)\n                        {\n                            result = TBs + ((GBs % factor) / (factor + 0.0));\n                            unit = \"TB\";\n                            return;\n                        }\n                        result = GBs + ((MBs % factor) / (factor + 0.0));\n                        unit = \"GB\";\n                        return;\n                    }\n                    result = MBs + ((KBs % factor) / (factor + 0.0));\n                    unit = \"MB\";\n                    return;\n                }\n                result = KBs + ((amount % factor) / (factor + 0.0));\n                unit = \"KB\";\n                return;\n            }\n            else\n            {\n                result = amount;\n                unit = \"B\";\n            }\n        }\n\n        public static string HumanFy(long amount)\n        {\n            ToHumanReadable(amount, out double result, out string unit);\n            return $\"{string.Format(\"{0:f1}\", result)} {unit}\";\n        }\n\n        public static string UrlEncode(string url)\n        {\n            return Uri.EscapeDataString(url);\n            //return  HttpUtility.UrlEncode(url);\n        }\n\n        public static string UrlDecode(string url)\n        {\n            return HttpUtility.UrlDecode(url);\n        }\n\n        public static string GetMD5(string str)\n        {\n            byte[] byteOld = Encoding.UTF8.GetBytes(str);\n            byte[] byteNew = MD5.HashData(byteOld);\n            StringBuilder sb = new(32);\n            foreach (byte b in byteNew)\n            {\n                sb.Append(b.ToString(\"x2\"));\n            }\n            return sb.ToString();\n        }\n\n        public static ImageSource IconToImageSource(Icon icon)\n        {\n            return Imaging.CreateBitmapSourceFromHIcon(\n                icon.Handle,\n                new System.Windows.Int32Rect(0, 0, icon.Width, icon.Height),\n                BitmapSizeOptions.FromEmptyOptions());\n        }\n\n        /// <summary>\n        /// idn to idc\n        /// </summary>\n        /// <param name=\"url\"></param>\n        /// <returns></returns>\n        public static string GetPunycode(string url)\n        {\n            if (string.IsNullOrWhiteSpace(url))\n            {\n                return url;\n            }\n            try\n            {\n                Uri uri = new(url);\n                if (uri.Host == uri.IdnHost)\n                {\n                    return url;\n                }\n                else\n                {\n                    return url.Replace(uri.Host, uri.IdnHost);\n                }\n            }\n            catch\n            {\n                return url;\n            }\n        }\n\n        public static bool IsBase64String(string plainText)\n        {\n            var buffer = new Span<byte>(new byte[plainText.Length]);\n            return Convert.TryFromBase64String(plainText, buffer, out int _);\n        }\n\n        public static string Convert2Comma(string text)\n        {\n            if (string.IsNullOrWhiteSpace(text))\n            {\n                return text;\n            }\n            return text.Replace(\"，\", \",\").Replace(Environment.NewLine, \",\");\n        }\n\n        #endregion 转换函数\n\n        #region 数据检查\n\n        /// <summary>\n        /// 判断输入的是否是数字\n        /// </summary>\n        /// <param name=\"oText\"></param>\n        /// <returns></returns>\n        public static bool IsNumberic(string oText)\n        {\n            try\n            {\n                int var1 = ToInt(oText);\n                return true;\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n                return false;\n            }\n        }\n\n        /// <summary>\n        /// 文本\n        /// </summary>\n        /// <param name=\"text\"></param>\n        /// <returns></returns>\n        public static bool IsNullOrEmpty(string? text)\n        {\n            if (string.IsNullOrEmpty(text))\n            {\n                return true;\n            }\n            if (text == \"null\")\n            {\n                return true;\n            }\n            return false;\n        }\n\n        /// <summary>\n        /// 验证IP地址是否合法\n        /// </summary>\n        /// <param name=\"ip\"></param>\n        public static bool IsIP(string ip)\n        {\n            //如果为空\n            if (IsNullOrEmpty(ip))\n            {\n                return false;\n            }\n\n            //清除要验证字符串中的空格\n            //ip = ip.TrimEx();\n            //可能是CIDR\n            if (ip.IndexOf(@\"/\") > 0)\n            {\n                string[] cidr = ip.Split('/');\n                if (cidr.Length == 2)\n                {\n                    if (!IsNumberic(cidr[0]))\n                    {\n                        return false;\n                    }\n                    ip = cidr[0];\n                }\n            }\n\n            //模式字符串\n            string pattern = @\"^((2[0-4]\\d|25[0-5]|[01]?\\d\\d?)\\.){3}(2[0-4]\\d|25[0-5]|[01]?\\d\\d?)$\";\n\n            //验证\n            return IsMatch(ip, pattern);\n        }\n\n        /// <summary>\n        /// 验证Domain地址是否合法\n        /// </summary>\n        /// <param name=\"domain\"></param>\n        public static bool IsDomain(string domain)\n        {\n            //如果为空\n            if (IsNullOrEmpty(domain))\n            {\n                return false;\n            }\n\n            return Uri.CheckHostName(domain) == UriHostNameType.Dns;\n        }\n\n        /// <summary>\n        /// 验证输入字符串是否与模式字符串匹配，匹配返回true\n        /// </summary>\n        /// <param name=\"input\">输入字符串</param>\n        /// <param name=\"pattern\">模式字符串</param>\n        public static bool IsMatch(string input, string pattern)\n        {\n            return Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);\n        }\n\n        public static bool IsIpv6(string ip)\n        {\n            if (IPAddress.TryParse(ip, out IPAddress? address))\n            {\n                return address.AddressFamily switch\n                {\n                    AddressFamily.InterNetwork => false,\n                    AddressFamily.InterNetworkV6 => true,\n                    _ => false,\n                };\n            }\n            return false;\n        }\n\n        #endregion 数据检查\n\n        #region 开机自动启动\n\n        /// <summary>\n        /// 开机自动启动\n        /// </summary>\n        /// <param name=\"run\"></param>\n        /// <returns></returns>\n        public static void SetAutoRun(bool run)\n        {\n            try\n            {\n                var autoRunName = $\"{Global.AutoRunName}_{GetMD5(StartupPath())}\";\n\n                //delete first\n                RegWriteValue(Global.AutoRunRegPath, autoRunName, \"\");\n                if (IsAdministrator())\n                {\n                    AutoStart(autoRunName, \"\", \"\");\n                }\n\n                if (run)\n                {\n                    string exePath = $\"\\\"{GetExePath()}\\\"\";\n                    if (IsAdministrator())\n                    {\n                        AutoStart(autoRunName, exePath, \"\");\n                    }\n                    else\n                    {\n                        RegWriteValue(Global.AutoRunRegPath, autoRunName, exePath);\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n        }\n\n        /// <summary>\n        /// 是否已经设置开机自动启动\n        /// </summary>\n        /// <returns></returns>\n        public static bool IsAutoRun()\n        {\n            try\n            {\n                //clear\n                if (!RegReadValue(Global.AutoRunRegPath, Global.AutoRunName, \"\").IsNullOrEmpty())\n                {\n                    RegWriteValue(Global.AutoRunRegPath, Global.AutoRunName, \"\");\n                }\n\n                string value = RegReadValue(Global.AutoRunRegPath, Global.AutoRunName, \"\");\n                string exePath = GetExePath();\n                if (value == exePath || value == $\"\\\"{exePath}\\\"\")\n                {\n                    return true;\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return false;\n        }\n\n        /// <summary>\n        /// 获取启动了应用程序的可执行文件的路径\n        /// </summary>\n        /// <returns></returns>\n        public static string GetPath(string fileName)\n        {\n            string startupPath = StartupPath();\n            if (IsNullOrEmpty(fileName))\n            {\n                return startupPath;\n            }\n            return Path.Combine(startupPath, fileName);\n        }\n\n        /// <summary>\n        /// 获取启动了应用程序的可执行文件的路径及文件名\n        /// </summary>\n        /// <returns></returns>\n        public static string GetExePath()\n        {\n            return Environment.ProcessPath;\n        }\n\n        public static string StartupPath()\n        {\n            return AppDomain.CurrentDomain.BaseDirectory;\n        }\n\n        public static string? RegReadValue(string path, string name, string def)\n        {\n            RegistryKey? regKey = null;\n            try\n            {\n                regKey = Registry.CurrentUser.OpenSubKey(path, false);\n                string? value = regKey?.GetValue(name) as string;\n                if (IsNullOrEmpty(value))\n                {\n                    return def;\n                }\n                else\n                {\n                    return value;\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            finally\n            {\n                regKey?.Close();\n            }\n            return def;\n        }\n\n        public static void RegWriteValue(string path, string name, object value)\n        {\n            RegistryKey? regKey = null;\n            try\n            {\n                regKey = Registry.CurrentUser.CreateSubKey(path);\n                if (IsNullOrEmpty(value.ToString()))\n                {\n                    regKey?.DeleteValue(name, false);\n                }\n                else\n                {\n                    regKey?.SetValue(name, value);\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            finally\n            {\n                regKey?.Close();\n            }\n        }\n\n        /// <summary>\n        /// 判断.Net Framework的Release是否符合\n        /// (.Net Framework 版本在4.0及以上)\n        /// </summary>\n        /// <param name=\"release\">需要的版本4.6.2=394802;4.8=528040</param>\n        /// <returns></returns>\n        public static bool CheckForDotNetVersion(int release = 528040)\n        {\n            const string subkey = @\"SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\\";\n            using RegistryKey? ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey);\n            if (ndpKey?.GetValue(\"Release\") != null)\n            {\n                return (int)ndpKey.GetValue(\"Release\") >= release;\n            }\n            return false;\n        }\n\n        /// <summary>\n        /// Auto Start via TaskService\n        /// </summary>\n        /// <param name=\"taskName\"></param>\n        /// <param name=\"fileName\"></param>\n        /// <param name=\"description\"></param>\n        /// <exception cref=\"ArgumentNullException\"></exception>\n        public static void AutoStart(string taskName, string fileName, string description)\n        {\n            if (string.IsNullOrEmpty(taskName))\n            {\n                return;\n            }\n            string TaskName = taskName;\n            var logonUser = WindowsIdentity.GetCurrent().Name;\n            string taskDescription = description;\n            string deamonFileName = fileName;\n\n            using var taskService = new TaskService();\n            var tasks = taskService.RootFolder.GetTasks(new Regex(TaskName));\n            foreach (var t in tasks)\n            {\n                taskService.RootFolder.DeleteTask(t.Name);\n            }\n            if (string.IsNullOrEmpty(fileName))\n            {\n                return;\n            }\n\n            var task = taskService.NewTask();\n            task.RegistrationInfo.Description = taskDescription;\n            task.Settings.DisallowStartIfOnBatteries = false;\n            task.Settings.StopIfGoingOnBatteries = false;\n            task.Settings.RunOnlyIfIdle = false;\n            task.Settings.IdleSettings.StopOnIdleEnd = false;\n            task.Settings.ExecutionTimeLimit = TimeSpan.Zero;\n            task.Triggers.Add(new LogonTrigger { UserId = logonUser, Delay = TimeSpan.FromSeconds(10) });\n            task.Principal.RunLevel = TaskRunLevel.Highest;\n            task.Actions.Add(new ExecAction(deamonFileName));\n\n            taskService.RootFolder.RegisterTaskDefinition(TaskName, task);\n        }\n\n        #endregion 开机自动启动\n\n        #region 测速\n\n        /// <summary>\n        /// 取得本机 IP Address\n        /// </summary>\n        /// <returns></returns>\n        //public static List<string> GetHostIPAddress()\n        //{\n        //    List<string> lstIPAddress = new List<string>();\n        //    try\n        //    {\n        //        IPHostEntry IpEntry = Dns.GetHostEntry(Dns.GetHostName());\n        //        foreach (IPAddress ipa in IpEntry.AddressList)\n        //        {\n        //            if (ipa.AddressFamily == AddressFamily.InterNetwork)\n        //                lstIPAddress.Add(ipa.ToString());\n        //        }\n        //    }\n        //    catch (Exception ex)\n        //    {\n        //        SaveLog(ex.Message, ex);\n        //    }\n        //    return lstIPAddress;\n        //}\n\n        public static void SetSecurityProtocol(bool enableSecurityProtocolTls13)\n        {\n            if (enableSecurityProtocolTls13)\n            {\n                ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12 | SecurityProtocolType.Tls13;\n            }\n            else\n            {\n                ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls12;\n            }\n            ServicePointManager.DefaultConnectionLimit = 256;\n        }\n\n        public static bool PortInUse(int port)\n        {\n            bool inUse = false;\n            try\n            {\n                IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();\n                IPEndPoint[] ipEndPoints = ipProperties.GetActiveTcpListeners();\n\n                var lstIpEndPoints = new List<IPEndPoint>(IPGlobalProperties.GetIPGlobalProperties().GetActiveTcpListeners());\n\n                foreach (IPEndPoint endPoint in ipEndPoints)\n                {\n                    if (endPoint.Port == port)\n                    {\n                        inUse = true;\n                        break;\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return inUse;\n        }\n\n        #endregion 测速\n\n        #region 杂项\n\n        /// <summary>\n        /// 取得版本\n        /// </summary>\n        /// <returns></returns>\n        public static string GetVersion(bool blFull = true)\n        {\n            try\n            {\n                string location = GetExePath();\n                if (blFull)\n                {\n                    return string.Format(\"HiddifyN - V{0} - {1}-Test\",\n                            FileVersionInfo.GetVersionInfo(location).FileVersion.ToString(),\n                            File.GetLastWriteTime(location).ToString(\"yyyy/MM/dd\"));\n                }\n                else\n                {\n                    return string.Format(\"HiddifyN/{0}\",\n                        FileVersionInfo.GetVersionInfo(location).FileVersion.ToString());\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n                return string.Empty;\n            }\n        }\n\n        /// <summary>\n        /// 深度拷贝\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"obj\"></param>\n        /// <returns></returns>\n        public static T DeepCopy<T>(T obj)\n        {\n            object retval;\n            MemoryStream ms = new MemoryStream();\n            BinaryFormatter bf = new BinaryFormatter();\n            //序列化成流\n            bf.Serialize(ms, obj);\n            ms.Seek(0, SeekOrigin.Begin);\n            //反序列化成对象\n            retval = bf.Deserialize(ms);\n            return (T)retval;\n        }\n\n        /// <summary>\n        /// 获取剪贴板数\n        /// </summary>\n        /// <returns></returns>\n        public static string? GetClipboardData()\n        {\n            string? strData = string.Empty;\n            try\n            {\n                IDataObject data = Clipboard.GetDataObject();\n                if (data.GetDataPresent(DataFormats.UnicodeText))\n                {\n                    strData = data.GetData(DataFormats.UnicodeText)?.ToString();\n                }\n                return strData;\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return strData;\n        }\n\n        /// <summary>\n        /// 拷贝至剪贴板\n        /// </summary>\n        /// <returns></returns>\n        public static void SetClipboardData(string strData)\n        {\n            try\n            {\n                Clipboard.SetText(strData);\n            }\n            catch\n            {\n            }\n        }\n\n        /// <summary>\n        /// 取得GUID\n        /// </summary>\n        /// <returns></returns>\n        public static string GetGUID(bool full = true)\n        {\n            try\n            {\n                if (full)\n                {\n                    return Guid.NewGuid().ToString(\"D\");\n                }\n                else\n                {\n                    return BitConverter.ToInt64(Guid.NewGuid().ToByteArray(), 0).ToString();\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return string.Empty;\n        }\n\n        /// <summary>\n        /// IsAdministrator\n        /// </summary>\n        /// <returns></returns>\n        public static bool IsAdministrator()\n        {\n            try\n            {\n                WindowsIdentity current = WindowsIdentity.GetCurrent();\n                WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current);\n                //WindowsBuiltInRole可以枚举出很多权限，例如系统用户、User、Guest等等\n                return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n                return false;\n            }\n        }\n\n        public static string GetDownloadFileName(string url)\n        {\n            var fileName = Path.GetFileName(url);\n            fileName += \"_temp\";\n\n            return fileName;\n        }\n\n        public static IPAddress? GetDefaultGateway()\n        {\n            return NetworkInterface\n                .GetAllNetworkInterfaces()\n                .Where(n => n.OperationalStatus == OperationalStatus.Up)\n                .Where(n => n.NetworkInterfaceType != NetworkInterfaceType.Loopback)\n                .SelectMany(n => n.GetIPProperties()?.GatewayAddresses)\n                .Select(g => g?.Address)\n                .Where(a => a != null)\n                // .Where(a => a.AddressFamily == AddressFamily.InterNetwork)\n                // .Where(a => Array.FindIndex(a.GetAddressBytes(), b => b != 0) >= 0)\n                .FirstOrDefault();\n        }\n\n        public static bool IsGuidByParse(string strSrc)\n        {\n            return Guid.TryParse(strSrc, out Guid g);\n        }\n\n        public static void ProcessStart(string fileName)\n        {\n            try\n            {\n                Process.Start(new ProcessStartInfo(fileName) { UseShellExecute = true });\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n        }\n\n        public static void SetDarkBorder(System.Windows.Window window, bool dark)\n        {\n            // Make sure the handle is created before the window is shown\n            IntPtr hWnd = new System.Windows.Interop.WindowInteropHelper(window).EnsureHandle();\n            int attribute = dark ? 1 : 0;\n            uint attributeSize = (uint)Marshal.SizeOf(attribute);\n            DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1, ref attribute, attributeSize);\n            DwmSetWindowAttribute(hWnd, DWMWINDOWATTRIBUTE.DWMWA_USE_IMMERSIVE_DARK_MODE, ref attribute, attributeSize);\n        }\n\n        #endregion 杂项\n\n        #region TempPath\n\n        // return path to store temporary files\n        public static string GetTempPath(string filename = \"\")\n        {\n            string _tempPath = Path.Combine(StartupPath(), \"guiTemps\");\n            if (!Directory.Exists(_tempPath))\n            {\n                Directory.CreateDirectory(_tempPath);\n            }\n            if (string.IsNullOrEmpty(filename))\n            {\n                return _tempPath;\n            }\n            else\n            {\n                return Path.Combine(_tempPath, filename);\n            }\n        }\n\n        public static string UnGzip(byte[] buf)\n        {\n            using MemoryStream sb = new();\n            using GZipStream input = new(new MemoryStream(buf), CompressionMode.Decompress, false);\n            input.CopyTo(sb);\n            sb.Position = 0;\n            return new StreamReader(sb, Encoding.UTF8).ReadToEnd();\n        }\n\n        public static string GetBackupPath(string filename)\n        {\n            string _tempPath = Path.Combine(StartupPath(), \"guiBackups\");\n            if (!Directory.Exists(_tempPath))\n            {\n                Directory.CreateDirectory(_tempPath);\n            }\n            return Path.Combine(_tempPath, filename);\n        }\n\n        public static string GetConfigPath(string filename = \"\")\n        {\n            string _tempPath = Path.Combine(StartupPath(), \"guiConfigs\");\n            if (!Directory.Exists(_tempPath))\n            {\n                Directory.CreateDirectory(_tempPath);\n            }\n            if (string.IsNullOrEmpty(filename))\n            {\n                return _tempPath;\n            }\n            else\n            {\n                return Path.Combine(_tempPath, filename);\n            }\n        }\n\n        public static string GetBinPath(string filename, ECoreType? coreType = null)\n        {\n            string _tempPath = Path.Combine(StartupPath(), \"bin\");\n            if (!Directory.Exists(_tempPath))\n            {\n                Directory.CreateDirectory(_tempPath);\n            }\n            if (coreType != null)\n            {\n                _tempPath = Path.Combine(_tempPath, coreType.ToString()!);\n                if (!Directory.Exists(_tempPath))\n                {\n                    Directory.CreateDirectory(_tempPath);\n                }\n            }\n            if (string.IsNullOrEmpty(filename))\n            {\n                return _tempPath;\n            }\n            else\n            {\n                return Path.Combine(_tempPath, filename);\n            }\n        }\n\n        public static string GetLogPath(string filename = \"\")\n        {\n            string _tempPath = Path.Combine(StartupPath(), \"guiLogs\");\n            if (!Directory.Exists(_tempPath))\n            {\n                Directory.CreateDirectory(_tempPath);\n            }\n            if (string.IsNullOrEmpty(filename))\n            {\n                return _tempPath;\n            }\n            else\n            {\n                return Path.Combine(_tempPath, filename);\n            }\n        }\n\n        public static string GetFontsPath(string filename = \"\")\n        {\n            string _tempPath = Path.Combine(StartupPath(), \"guiFonts\");\n            if (!Directory.Exists(_tempPath))\n            {\n                Directory.CreateDirectory(_tempPath);\n            }\n            if (string.IsNullOrEmpty(filename))\n            {\n                return _tempPath;\n            }\n            else\n            {\n                return Path.Combine(_tempPath, filename);\n            }\n        }\n\n        #endregion TempPath\n\n        #region Log\n\n        public static void SaveLog(string strContent)\n        {\n            if (LogManager.IsLoggingEnabled())\n            {\n                var logger = LogManager.GetLogger(\"Log1\");\n                logger.Info(strContent);\n            }\n        }\n\n        public static void SaveLog(string strTitle, Exception ex)\n        {\n            if (LogManager.IsLoggingEnabled())\n            {\n                var logger = LogManager.GetLogger(\"Log2\");\n                logger.Debug($\"{strTitle},{ex.Message}\");\n                logger.Debug(ex.StackTrace);\n                if (ex?.InnerException != null)\n                {\n                    logger.Error(ex.InnerException);\n                }\n            }\n        }\n\n        #endregion Log\n\n        #region scan screen\n\n        public static string ScanScreen(float dpiX, float dpiY)\n        {\n            try\n            {\n                var left = (int)(SystemParameters.WorkArea.Left);\n                var top = (int)(SystemParameters.WorkArea.Top);\n                var width = (int)(SystemParameters.WorkArea.Width / dpiX);\n                var height = (int)(SystemParameters.WorkArea.Height / dpiY);\n\n                using Bitmap fullImage = new Bitmap(width, height);\n                using (Graphics g = Graphics.FromImage(fullImage))\n                {\n                    g.CopyFromScreen(left, top, 0, 0, fullImage.Size, CopyPixelOperation.SourceCopy);\n                }\n                int maxTry = 10;\n                for (int i = 0; i < maxTry; i++)\n                {\n                    int marginLeft = (int)((double)fullImage.Width * i / 2.5 / maxTry);\n                    int marginTop = (int)((double)fullImage.Height * i / 2.5 / maxTry);\n                    Rectangle cropRect = new(marginLeft, marginTop, fullImage.Width - marginLeft * 2, fullImage.Height - marginTop * 2);\n                    Bitmap target = new(width, height);\n\n                    double imageScale = (double)width / (double)cropRect.Width;\n                    using (Graphics g = Graphics.FromImage(target))\n                    {\n                        g.DrawImage(fullImage, new Rectangle(0, 0, target.Width, target.Height),\n                                        cropRect,\n                                        GraphicsUnit.Pixel);\n                    }\n\n                    BitmapLuminanceSource source = new(target);\n                    BinaryBitmap bitmap = new(new HybridBinarizer(source));\n                    QRCodeReader reader = new();\n                    Result result = reader.decode(bitmap);\n                    if (result != null)\n                    {\n                        string ret = result.Text;\n                        return ret;\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                SaveLog(ex.Message, ex);\n            }\n            return string.Empty;\n        }\n\n        public static Tuple<float, float> GetDpiXY(Window window)\n        {\n            IntPtr hWnd = new WindowInteropHelper(window).EnsureHandle();\n            Graphics g = Graphics.FromHwnd(hWnd);\n\n            return new(96 / g.DpiX, 96 / g.DpiY);\n        }\n\n        #endregion scan screen\n\n        #region Windows API\n\n        [Flags]\n        public enum DWMWINDOWATTRIBUTE : uint\n        {\n            DWMWA_USE_IMMERSIVE_DARK_MODE_BEFORE_20H1 = 19,\n            DWMWA_USE_IMMERSIVE_DARK_MODE = 20,\n        }\n\n        [DllImport(\"dwmapi.dll\")]\n        public static extern int DwmSetWindowAttribute(IntPtr hwnd, DWMWINDOWATTRIBUTE attribute, ref int attributeValue, uint attributeSize);\n\n        #endregion Windows API\n\n        // It doesn't really lock the file, because if the program be closed, the file will be unlocked\n        // Instead of that, it will write locked in the file\n        private static void LockMainFormReloadFile()\n        {\n            File.WriteAllText(Global.MainFormReloadFilePath, \"locked\");\n        }\n        private static void UnlockMainFormReloadFile()\n        {\n            File.WriteAllText(Global.MainFormReloadFilePath, \"unlocked\");\n        }\n        private static bool IsMainFormReloadFileLocked()\n        {\n           if (!File.Exists(Global.MainFormReloadFilePath))\n           {\n                return false;\n           }\n           string content = File.ReadAllText(Global.MainFormReloadFilePath);\n           if (content == \"locked\")\n           {\n                return true;\n           }\n           else if (content == \"unlocked\")\n           {\n                return false;\n           }\n           else\n           {\n                throw new Exception($\"the {Global.MainFormReloadFilePath} lock file, abnormaly changed, please delete it\");\n           }\n        }\n\n        public static void SetMainPageReload()\n        {\n            bool tryAgain = false;\n            do\n            {\n                try\n                {\n                    LockMainFormReloadFile();\n                }\n                catch (Exception)\n                {\n                    tryAgain = true;\n                }\n\n            } while (tryAgain);\n        }\n        public static void UnsetMainPageReload()\n        {\n            bool tryAgain = false;\n            do\n            {\n                try\n                {\n                    UnlockMainFormReloadFile();\n                }\n                catch (Exception)\n                {\n                    tryAgain = true;\n                }\n            }while(tryAgain);\n        }\n        public static bool DoesMainPageNeedReload()\n        {\n            return IsMainFormReloadFileLocked();\n        }\n        public static void ExitSuccess()\n        {\n            System.Windows.Application.Current.Shutdown();\n            //int id = GetAppProcessID();\n            //Process.GetProcessById(id).Kill(true);\n            Environment.Exit(0);\n        }\n        public static void ExitError(int err)\n        {\n            System.Windows.Application.Current.Shutdown();\n            //int id = GetAppProcessID();\n            //Process.GetProcessById(id).Kill(true);\n            Environment.Exit(err);\n        }\n        public static int GetAppProcessID()\n        {\n            return Process.GetCurrentProcess().Id;\n        }\n        public static IWebProxy GetAppProxyAddress()\n        {\n            var httpPort = LazyConfig.Instance.GetLocalPort(Global.InboundHttp);\n\n            return new WebProxy(Global.Loopback, httpPort);\n        }\n        public static void RestartProgram(bool asAdmin = false)\n        {\n            new Thread(delegate ()\n            {\n                var mainProgramID = GetAppProcessID();\n                var pInfo = new ProcessStartInfo();\n                pInfo.FileName = Global.RestartProgramExePath;\n                pInfo.WorkingDirectory = Environment.CurrentDirectory;\n                if (asAdmin)\n                {\n                    pInfo.Arguments = $\"{mainProgramID} --a\";\n                }\n                else\n                {\n                    pInfo.Arguments = $\"{mainProgramID}\";\n                }\n                pInfo.CreateNoWindow = true;\n\n                Process.Start(pInfo);\n\n            }).Start();\n        }\n        // I think it's the right way\n        public static bool IsSystemProxyEnabled(ESysProxyType sysProxyType)\n        {\n            if (sysProxyType == ESysProxyType.ForcedChange || sysProxyType == ESysProxyType.Pac)\n            {\n                return true;\n            }\n            return false;\n        }\n\n        public static string? ExtractNameParameterFromUri(string uri)\n        {\n            // Extract name\n            if (uri.Contains(\"name=\"))\n            {\n                var splitted = uri.Split(\"name=\");\n                if (splitted.Length > 1)\n                {\n                    string name = \"\";\n                    foreach (char c in splitted[1].ToCharArray())\n                    {\n                        if (c == '&' || c == '?')\n                        {\n                            break;\n                        }\n                        name += c;\n                    }\n                    return name;\n                }\n            }\n            return null;\n        }\n        public static string? ExtractUrlParameterFromUri(string uri)\n        {\n            var splitted = uri.Split(\"url=\");\n            string? url = \"\";\n            if (splitted.Length > 1)\n            {\n                foreach (char c in splitted[1].ToCharArray())\n                {\n                    if (c == '&' || c == '?')\n                    {\n                        break;\n                    }\n                    url += c;\n                }\n            }\n            if (Utils.IsNullOrEmpty(url))\n            {\n                return null;\n            }\n            return url;\n        }\n\n        public static string ChangeHiddifySubDeeplinkToNormalSubUri(string hiddifySubDepplink)\n        {\n            // Valid uri sample: hiddify://install-sub?url=domain.com/path/clash.yml&name=sub_name\n            // We need after \"url=\" part\n\n            // Remove \"hiddify://install-sub?\"\n            if (hiddifySubDepplink.Contains(\"url=\"))\n            {\n                return System.Web.HttpUtility.UrlDecode(hiddifySubDepplink.Split(\"url=\")[1]);\n\n            }\n            return hiddifySubDepplink;\n        }\n\n        public static HttpResponseHeaders? GetUrlResponseHeader(string url, bool useProgramProxy)\n        {\n            HttpClientHandler handler;\n            if (!useProgramProxy)\n                handler = new HttpClientHandler() { UseProxy = false };\n            else\n                handler = new HttpClientHandler() { UseProxy = true };\n\n            using (var client = new HttpClient(handler))\n            {\n                System.Net.ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;\n                client.DefaultRequestHeaders.Accept.Clear();\n                try\n                {\n                    var response = client.Send(new HttpRequestMessage(HttpMethod.Head,url));\n                    if (response.StatusCode == HttpStatusCode.OK)\n                    {\n                        return response.Headers;\n                    }\n                }\n                catch (Exception)\n                {\n                    return null;\n                }\n            }\n            return null;\n        }\n        public async static Task<HttpStatusCode?> GetUrlResponseStatusCode(string url,bool useProgramProxy)\n        {\n            HttpClientHandler handler;\n            if (!useProgramProxy)\n                handler = new HttpClientHandler() { UseProxy = false};\n            else\n                handler = new HttpClientHandler() {  UseProxy =true};\n\n            using (var client = new HttpClient(handler))\n            {\n                ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;\n                client.DefaultRequestHeaders.Accept.Clear();\n                try\n                {\n                    var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));\n                    return response.StatusCode;\n                }\n                catch (Exception)\n                {\n                    return null;\n                }\n            }\n        }\n\n        public async static Task<bool> IsUrlStatusCode204(string url, bool useProgramProxy)\n        {\n            HttpClientHandler handler;\n            if (!useProgramProxy)\n                handler = new HttpClientHandler() { UseProxy = false };\n            else\n                handler = new HttpClientHandler() { UseProxy = true };\n\n            using (var client = new HttpClient(handler))\n            {\n                ServicePointManager.SecurityProtocol |= SecurityProtocolType.Tls13 | SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;\n                client.DefaultRequestHeaders.Accept.Clear();\n                try\n                {\n                    var response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Head, url));\n                    if (response.StatusCode == HttpStatusCode.NoContent)\n                        return true;\n                    else\n                        return false;\n                }\n                catch (Exception)\n                {\n                    return false;\n                }\n            }\n        }\n\n        public static DateTime EpochToDate(long epoch)\n        {\n            return DateTimeOffset.FromUnixTimeSeconds(epoch).DateTime;\n        }\n\n\n        public static string? GetHostAndFirstTwoPathInUri(string url)\n        {\n            // For example:\n            //   https://domain.com/first/two/all.txt?parameter=value\n            // Will be:\n            //   https://domain.com/first/two/\n\n            Uri uri = new Uri(url);\n            string[] splitted = uri.AbsolutePath.TrimStart('/').Split('/', 3);\n            if (splitted.Length < 3)\n            {\n                return null;\n            }\n            return uri.Scheme + \"://\" + uri.Host + '/' + splitted[0] + '/' + splitted[1] + '/';\n\n        }\n\n        // First return value is for stdout and second one is for stderr\n        public static (string?,string?) StartProcess(ProcessStartInfo sInfo)\n        {\n            var errors = new StringBuilder();\n            var output = new StringBuilder();\n\n            var hadError = false;\n\n            var p = Process.Start(sInfo);\n            p.EnableRaisingEvents = true;\n\n            p.OutputDataReceived += (s, d) =>\n            {\n                output.Append(d.Data);\n            };\n\n            p.ErrorDataReceived += (s, d) =>\n            {\n                if (!hadError)\n                {\n                    hadError = !String.IsNullOrEmpty(d.Data);\n                }\n                errors.Append(d.Data);\n            };\n\n            p.BeginErrorReadLine();\n            p.BeginOutputReadLine();\n            p.WaitForExit();\n\n            string stdout = output.ToString();\n            string stderr = errors.ToString();\n            if (p.ExitCode != 0 || hadError)\n            {\n                return (null,stderr);\n            }\n            return (stdout,null);\n        }\n        #region Clash Subscription Info\n        public static SubscriptionInfo? GetSubscriptionInfoFromHeaders(HttpResponseHeaders headers)\n        {\n            if (headers == null)\n            {\n                return null;\n            }\n            SubscriptionInfo clashSubscriptionInfo = new SubscriptionInfo();\n\n            IEnumerable<string> userSubInfoValues;\n            if (headers.TryGetValues(\"Subscription-Userinfo\", out userSubInfoValues))\n            {\n                // Split values\n                foreach (var item in userSubInfoValues.FirstOrDefault().Split(\";\"))\n                {\n                    // Split key and values\n                    int equalsSignIndex = item.IndexOf(\"=\");\n                    string key = item.Substring(0, equalsSignIndex);\n                    string value = item.Substring(equalsSignIndex + 1);\n\n                    if (key == \"upload\")\n                    {\n                        long longValue;\n                        if (long.TryParse(value, out longValue))\n                        {\n                            clashSubscriptionInfo.Upload = longValue;\n                        }\n                    }\n                    else if (key == \"download\")\n                    {\n                        long longValue;\n                        if (long.TryParse(value, out longValue))\n                        {\n                            clashSubscriptionInfo.Download = longValue;\n                        }\n                    }\n                    else if (key == \"total\")\n                    {\n                        long longValue;\n                        if (long.TryParse(value, out longValue))\n                        {\n                            clashSubscriptionInfo.Total = longValue;\n                        }\n                    }\n                    else if (key == \"expire\")\n                    {\n                        long longValue;\n                        if (long.TryParse(value, out longValue))\n                        {\n                            clashSubscriptionInfo.ExpireDate = longValue;\n                        }\n\n                    }\n                }\n                \n            }\n\n\n            // Get profile web page url from header\n            IEnumerable<string> profileWebPageValue;\n            if (headers.TryGetValues(\"Profile-Web-Page-Url\",out profileWebPageValue))\n            {\n                string profileWebPageUrl = profileWebPageValue.FirstOrDefault();\n                if (profileWebPageUrl != null)\n                    clashSubscriptionInfo.ProfileWebPageUrl = profileWebPageUrl;\n            }\n\n            IEnumerable<string> profileTitleValue;\n            if (headers.TryGetValues(\"Profile-Title\", out profileTitleValue))\n            {\n                string profileTitle = profileTitleValue.FirstOrDefault();\n                if (profileTitle != null)\n                    clashSubscriptionInfo.ProfileTitle = profileTitle;\n            }\n\n            IEnumerable<string> profileUpdateIntervalValue;\n            if (headers.TryGetValues(\"Profile-Update-Interval\",out profileUpdateIntervalValue))\n            {\n                int profileUpdateInterval = Convert.ToInt32(profileUpdateIntervalValue.FirstOrDefault());\n                if (profileUpdateIntervalValue != null)\n                    clashSubscriptionInfo.ProfileUpdateInterval = profileUpdateInterval;\n            }\n            return clashSubscriptionInfo;\n        }\n\n        public int CalculateRemaningExpireDays(DateTime dateTime)\n        {\n            return DateTime.Now.Subtract(dateTime).Days;\n        }\n        #endregion\n    }\n    \n\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/AddServer2ViewModel.cs",
    "content": "using Microsoft.Win32;\nusing ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing ReactiveUI.Validation.Helpers;\nusing Splat;\nusing System.IO;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.ViewModels\n{\n    public class AddServer2ViewModel : ReactiveValidationObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n\n        [Reactive]\n        public ProfileItem SelectedSource { get; set; }\n\n        public ReactiveCommand<Unit, Unit> BrowseServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> EditServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> SaveServerCmd { get; }\n        public bool IsModified { get; set; }\n\n        public AddServer2ViewModel(ProfileItem profileItem, Window view)\n        {\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _config = LazyConfig.Instance.GetConfig();\n\n            if (profileItem.indexId.IsNullOrEmpty())\n            {\n                SelectedSource = profileItem;\n            }\n            else\n            {\n                SelectedSource = Utils.DeepCopy(profileItem);\n            }\n\n            _view = view;\n\n            BrowseServerCmd = ReactiveCommand.Create(() =>\n            {\n                BrowseServer();\n            });\n\n            EditServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer();\n            });\n\n            SaveServerCmd = ReactiveCommand.Create(() =>\n            {\n                SaveServer();\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        private void SaveServer()\n        {\n            string remarks = SelectedSource.remarks;\n            if (Utils.IsNullOrEmpty(remarks))\n            {\n                UI.Show(ResUI.PleaseFillRemarks);\n                return;\n            }\n\n            if (Utils.IsNullOrEmpty(SelectedSource.address))\n            {\n                UI.Show(ResUI.FillServerAddressCustom);\n                return;\n            }\n\n            var item = LazyConfig.Instance.GetProfileItem(SelectedSource.indexId);\n            if (item is null)\n            {\n                item = SelectedSource;\n            }\n            else\n            {\n                item.remarks = SelectedSource.remarks;\n                item.address = SelectedSource.address;\n                item.coreType = SelectedSource.coreType;\n                item.displayLog = SelectedSource.displayLog;\n                item.preSocksPort = SelectedSource.preSocksPort;\n            }\n\n            if (ConfigHandler.EditCustomServer(ref _config, item) == 0)\n            {\n                _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n                _view.DialogResult = true;\n            }\n            else\n            {\n                UI.Show(ResUI.OperationFailed);\n            }\n        }\n\n        private void BrowseServer()\n        {\n            UI.Show(ResUI.CustomServerTips);\n\n            OpenFileDialog fileDialog = new()\n            {\n                Multiselect = false,\n                Filter = \"Config|*.json|YAML|*.yaml;*.yml|All|*.*\"\n            };\n            if (fileDialog.ShowDialog() != true)\n            {\n                return;\n            }\n            string fileName = fileDialog.FileName;\n            if (Utils.IsNullOrEmpty(fileName))\n            {\n                return;\n            }\n            var item = LazyConfig.Instance.GetProfileItem(SelectedSource.indexId);\n            item ??= SelectedSource;\n            item.address = fileName;\n            if (ConfigHandler.AddCustomServer(ref _config, item, false) == 0)\n            {\n                _noticeHandler?.Enqueue(ResUI.SuccessfullyImportedCustomServer);\n                if (!Utils.IsNullOrEmpty(item.indexId))\n                {\n                    SelectedSource = Utils.DeepCopy(item);\n                }\n                IsModified = true;\n            }\n            else\n            {\n                UI.ShowWarning(ResUI.FailedImportedCustomServer);\n            }\n        }\n\n        private void EditServer()\n        {\n            var address = SelectedSource.address;\n            if (Utils.IsNullOrEmpty(address))\n            {\n                UI.Show(ResUI.FillServerAddressCustom);\n                return;\n            }\n\n            address = Utils.GetConfigPath(address);\n            if (File.Exists(address))\n            {\n                Utils.ProcessStart(address);\n            }\n            else\n            {\n                _noticeHandler?.Enqueue(ResUI.FailedReadConfiguration);\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/AddServerViewModel.cs",
    "content": "﻿using ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.ViewModels\n{\n    public class AddServerViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n\n        [Reactive]\n        public ProfileItem SelectedSource { get; set; }\n\n        public ReactiveCommand<Unit, Unit> SaveCmd { get; }\n\n        public AddServerViewModel(ProfileItem profileItem, Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _view = view;\n\n            if (profileItem.id.IsNullOrEmpty())\n            {\n                profileItem.network = Global.DefaultNetwork;\n                profileItem.headerType = Global.None;\n                profileItem.requestHost = \"\";\n                profileItem.streamSecurity = \"\";\n                SelectedSource = profileItem;\n            }\n            else\n            {\n                SelectedSource = Utils.DeepCopy(profileItem);\n            }\n\n            SaveCmd = ReactiveCommand.Create(() =>\n            {\n                SaveServer();\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        private void SaveServer()\n        {\n            if (Utils.IsNullOrEmpty(SelectedSource.remarks))\n            {\n                UI.Show(ResUI.PleaseFillRemarks);\n                return;\n            }\n\n            if (Utils.IsNullOrEmpty(SelectedSource.address))\n            {\n                UI.Show(ResUI.FillServerAddress);\n                return;\n            }\n            var port = SelectedSource.port.ToString();\n            if (Utils.IsNullOrEmpty(port) || !Utils.IsNumberic(port)\n                || SelectedSource.port <= 0 || SelectedSource.port >= Global.MaxPort)\n            {\n                UI.Show(ResUI.FillCorrectServerPort);\n                return;\n            }\n            if (SelectedSource.configType == EConfigType.Shadowsocks)\n            {\n                if (Utils.IsNullOrEmpty(SelectedSource.id))\n                {\n                    UI.Show(ResUI.FillPassword);\n                    return;\n                }\n                if (Utils.IsNullOrEmpty(SelectedSource.security))\n                {\n                    UI.Show(ResUI.PleaseSelectEncryption);\n                    return;\n                }\n            }\n            if (SelectedSource.configType != EConfigType.Socks)\n            {\n                if (Utils.IsNullOrEmpty(SelectedSource.id))\n                {\n                    UI.Show(ResUI.FillUUID);\n                    return;\n                }\n            }\n\n            var item = LazyConfig.Instance.GetProfileItem(SelectedSource.indexId);\n            if (item is null)\n            {\n                item = SelectedSource;\n            }\n            else\n            {\n                item.coreType = SelectedSource.coreType;\n                item.remarks = SelectedSource.remarks;\n                item.address = SelectedSource.address;\n                item.port = SelectedSource.port;\n\n                item.id = SelectedSource.id;\n                item.alterId = SelectedSource.alterId;\n                item.security = SelectedSource.security;\n                item.flow = SelectedSource.flow;\n\n                item.network = SelectedSource.network;\n                item.headerType = SelectedSource.headerType;\n                item.requestHost = SelectedSource.requestHost;\n                item.path = SelectedSource.path;\n                item.fragment = SelectedSource.fragment;\n\n                item.streamSecurity = SelectedSource.streamSecurity;\n                item.sni = SelectedSource.sni;\n                item.allowInsecure = SelectedSource.allowInsecure;\n                item.fingerprint = SelectedSource.fingerprint;\n                item.alpn = SelectedSource.alpn;\n\n                item.publicKey = SelectedSource.publicKey;\n                item.shortId = SelectedSource.shortId;\n                item.spiderX = SelectedSource.spiderX;\n            }\n\n            int ret = -1;\n            switch (item.configType)\n            {\n                case EConfigType.VMess:\n                    ret = ConfigHandler.AddServer(ref _config, item);\n                    break;\n\n                case EConfigType.Shadowsocks:\n                    ret = ConfigHandler.AddShadowsocksServer(ref _config, item);\n                    break;\n\n                case EConfigType.Socks:\n                    ret = ConfigHandler.AddSocksServer(ref _config, item);\n                    break;\n\n                case EConfigType.VLESS:\n                    ret = ConfigHandler.AddVlessServer(ref _config, item);\n                    break;\n\n                case EConfigType.Trojan:\n                    ret = ConfigHandler.AddTrojanServer(ref _config, item);\n                    break;\n            }\n\n            if (ret == 0)\n            {\n                _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n                _view.DialogResult = true;\n                //_view?.Close();\n            }\n            else\n            {\n                UI.Show(ResUI.OperationFailed);\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/AnotherCommandImplementation.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Input;\n\nnamespace v2rayN.ViewModels\n{\n    public class AnotherCommandImplementation : ICommand\n    {\n        private readonly Action<object?> _execute;\n        private readonly Func<object?, bool> _canExecute;\n\n        public AnotherCommandImplementation(Action<object?> execute)\n            : this(execute, null)\n        { }\n\n        public AnotherCommandImplementation(Action<object?> execute, Func<object?, bool>? canExecute)\n        {\n            if (execute is null) throw new ArgumentNullException(nameof(execute));\n\n            _execute = execute;\n            _canExecute = canExecute ?? (x => true);\n        }\n\n        public bool CanExecute(object? parameter) => _canExecute(parameter);\n\n        public void Execute(object? parameter) => _execute(parameter);\n\n        public event EventHandler? CanExecuteChanged\n        {\n            add\n            {\n                CommandManager.RequerySuggested += value;\n            }\n            remove\n            {\n                CommandManager.RequerySuggested -= value;\n            }\n        }\n\n        public void Refresh() => CommandManager.InvalidateRequerySuggested();\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs",
    "content": "﻿using ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.ViewModels\n{\n    public class DNSSettingViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n\n        [Reactive] public string domainStrategy4Freedom { get; set; }\n        [Reactive] public string normalDNS { get; set; }\n        [Reactive] public string normalDNS2 { get; set; }\n\n        public ReactiveCommand<Unit, Unit> SaveCmd { get; }\n        public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }\n        public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; }\n\n        public DNSSettingViewModel(Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _view = view;\n\n            var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);\n            domainStrategy4Freedom = item?.domainStrategy4Freedom!;\n            normalDNS = item?.normalDNS!;\n\n            var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);\n            normalDNS2 = item2?.normalDNS!;\n\n            SaveCmd = ReactiveCommand.Create(() =>\n            {\n                SaveSetting();\n            });\n\n            ImportDefConfig4V2rayCmd = ReactiveCommand.Create(() =>\n            {\n                normalDNS = Utils.GetEmbedText(Global.DNSV2rayNormalFileName);\n            });\n\n            ImportDefConfig4SingboxCmd = ReactiveCommand.Create(() =>\n            {\n                normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        private void SaveSetting()\n        {\n            if (!Utils.IsNullOrEmpty(normalDNS))\n            {\n                var obj = Utils.ParseJson(normalDNS);\n                if (obj != null && obj.ContainsKey(\"servers\") == true)\n                {\n                }\n                else\n                {\n                    if (normalDNS.Contains(\"{\") || normalDNS.Contains(\"}\"))\n                    {\n                        UI.Show(ResUI.FillCorrectDNSText);\n                        return;\n                    }\n                }\n            }\n            if (!Utils.IsNullOrEmpty(normalDNS2))\n            {\n                var obj2 = Utils.FromJson<Dns4Sbox>(normalDNS2);\n                if (obj2 == null)\n                {\n                    UI.Show(ResUI.FillCorrectDNSText);\n                    return;\n                }\n            }\n\n            var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);\n            item.domainStrategy4Freedom = domainStrategy4Freedom;\n            item.normalDNS = normalDNS;\n            ConfigHandler.SaveDNSItems(_config, item);\n\n            var item2 = LazyConfig.Instance.GetDNSItem(ECoreType.sing_box);\n            item2.normalDNS = Utils.ToJson(Utils.ParseJson(normalDNS2));\n            ConfigHandler.SaveDNSItems(_config, item2);\n\n            _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n            _view.DialogResult = true;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/DemoItem.cs",
    "content": "﻿using MaterialDesignThemes.Wpf;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Controls;\nusing System.Windows;\n\nnamespace v2rayN.ViewModels\n{\n    public class DemoItem : ViewModelBase\n    {\n        private readonly Type _contentType;\n        private readonly object? _dataContext;\n\n        private object? _content;\n        private ScrollBarVisibility _horizontalScrollBarVisibilityRequirement;\n        private ScrollBarVisibility _verticalScrollBarVisibilityRequirement = ScrollBarVisibility.Auto;\n        private Thickness _marginRequirement = new(16);\n\n        private int _notificationNumber = 0;\n\n        public DemoItem(string name, Type contentType,\n            PackIconKind selectedIcon, PackIconKind unselectedIcon, object? dataContext = null)\n        {\n            Name = name;\n            _contentType = contentType;\n            _dataContext = dataContext;\n\n            SelectedIcon = selectedIcon;\n            UnselectedIcon = unselectedIcon;\n        }\n\n        public string Name { get; }\n\n\n        public object? Content => _content ??= CreateContent();\n\n        public PackIconKind SelectedIcon { get; set; }\n        public PackIconKind UnselectedIcon { get; set; }\n\n        public object? Notifications\n        {\n            get\n            {\n                if (_notificationNumber == 0) return null;\n                else return _notificationNumber < 100 ? _notificationNumber : \"99+\";\n            }\n        }\n\n        public ScrollBarVisibility HorizontalScrollBarVisibilityRequirement\n        {\n            get => _horizontalScrollBarVisibilityRequirement;\n            set => SetProperty(ref _horizontalScrollBarVisibilityRequirement, value);\n        }\n\n        public ScrollBarVisibility VerticalScrollBarVisibilityRequirement\n        {\n            get => _verticalScrollBarVisibilityRequirement;\n            set => SetProperty(ref _verticalScrollBarVisibilityRequirement, value);\n        }\n\n        public Thickness MarginRequirement\n        {\n            get => _marginRequirement;\n            set => SetProperty(ref _marginRequirement, value);\n        }\n\n        private object? CreateContent()\n        {\n            var content = Activator.CreateInstance(_contentType);\n            if (_dataContext != null && content is FrameworkElement element)\n            {\n                element.DataContext = _dataContext;\n            }\n\n            return content;\n        }\n\n        public void AddNewNotification()\n        {\n            _notificationNumber++;\n            OnPropertyChanged(nameof(Notifications));\n        }\n\n        public void DismissAllNotifications()\n        {\n            _notificationNumber = 0;\n            OnPropertyChanged(nameof(Notifications));\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/HomeWindowViewModel.cs",
    "content": "﻿using Google.Protobuf.Collections;\nusing Google.Protobuf.WellKnownTypes;\nusing MaterialDesignThemes.Wpf;\nusing MaterialDesignThemes.Wpf.Transitions;\nusing System;\nusing System.Collections.Generic;\nusing System.Collections.ObjectModel;\nusing System.ComponentModel;\nusing System.Configuration;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing v2rayN.Views;\n\nusing v2rayN.ViewModels;\nusing v2rayN.Converters;\nusing v2rayN.Mode;\n\nnamespace v2rayN.ViewModels\n{\n    public class HomeWindowViewModel : ViewModelBase\n    {\n\n        public HomeWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue)\n        {\n            _snackbarMessageQueue = snackbarMessageQueue;\n            DemoItems = new ObservableCollection<DemoItem>\n            {\n              new DemoItem(\n                    \"Home\",\n                    typeof(MainWindow),\n                    selectedIcon: PackIconKind.Home,\n                    unselectedIcon: PackIconKind.HomeOutline)\n            };\n\n\n            MainDemoItems = new ObservableCollection<DemoItem>\n            {\n            };\n\n            _demoItemsView = CollectionViewSource.GetDefaultView(DemoItems);\n\n\n\n            DismissAllNotificationsCommand = new AnotherCommandImplementation(\n                _ => DemoItems[0].DismissAllNotifications(),\n                _ => DemoItems[0].Notifications != null);\n\n            AddNewNotificationCommand = new AnotherCommandImplementation(\n                _ => DemoItems[0].AddNewNotification());\n\n            AddNewNotificationCommand.Execute(new object());\n\n            NewProfileCommand = new AnotherCommandImplementation(ExecuteNewProfileDialog);\n            Items1 = new ObservableCollection<SubItem>()\n            {\n                _selectedProfile,\n                new SubItem\n                {\n                    id = \"A\",\n                    remarks = \"Profile2\",\n                    url= \"XAML Toolkit\"\n                },\n                new SubItem\n                {\n                    id = \"B\",\n                    remarks = \"Profile3\",\n                    url= \"Material Design in XAML Toolkit\"\n                },\n                new SubItem\n                {\n                    id = \"C\",\n                    remarks = \"Profile4\",\n                    url= \"Material \"\n                },\n            };\n\n        }\n        private async void ExecuteNewProfileDialog(object? _)\n        {\n            //let's set up a little MVVM, cos that's what the cool kids are doing:\n\n\n            //show the dialog\n            _snackbarMessageQueue.Enqueue(\"Nothing find in the Clipboard\");\n\n            //check the result...\n\n        }\n        private SubItem _selectedProfile = new SubItem\n        {\n            id = \"A\",\n            remarks = \"Profile 1\",\n            url = \"XAML Toolkit\"\n        };\n    public SubItem SelectedProfile { get => _selectedProfile; set => SetProperty(ref _selectedProfile, value); } \n    public ObservableCollection<SubItem> Items1 { get; } \n    \n        private readonly ICollectionView _demoItemsView;\n        private DemoItem? _selectedItem;\n        private int _selectedIndex;\n        private string? _searchKeyword;\n        private bool _controlsEnabled = true;\n        private ISnackbarMessageQueue _snackbarMessageQueue;\n\n        public ObservableCollection<DemoItem> DemoItems { get; }\n        public ObservableCollection<DemoItem> MainDemoItems { get; }\n\n        public DemoItem? SelectedItem\n        {\n            get => _selectedItem;\n            set => SetProperty(ref _selectedItem, value);\n        }\n\n        public int SelectedIndex\n        {\n            get => _selectedIndex;\n            set => SetProperty(ref _selectedIndex, value);\n        }\n        private bool _connectProgress = false;\n        public bool ConnectProgress {\n            get =>_connectProgress; \n            set => SetProperty(ref _connectProgress, value); \n        }\n        public bool ControlsEnabled\n        {\n            get => _controlsEnabled;\n            set => SetProperty(ref _controlsEnabled, value);\n        }\n\n        \n        public AnotherCommandImplementation DismissAllNotificationsCommand { get; }\n        public AnotherCommandImplementation AddNewNotificationCommand { get; }\n        public AnotherCommandImplementation NewProfileCommand { get; }\n\n        private static IEnumerable<DemoItem> GenerateDemoItems(ISnackbarMessageQueue snackbarMessageQueue)\n        {\n            if (snackbarMessageQueue is null)\n                throw new ArgumentNullException(nameof(snackbarMessageQueue));\n\n            yield return null;\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs",
    "content": "using DynamicData;\nusing DynamicData.Binding;\nusing MaterialDesignColors;\nusing MaterialDesignColors.ColorManipulation;\nusing MaterialDesignThemes.Wpf;\nusing Microsoft.Win32;\nusing ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System;\nusing System.ComponentModel;\nusing System.Diagnostics;\nusing System.DirectoryServices.ActiveDirectory;\nusing System.Drawing;\nusing System.Globalization;\nusing System.IO;\nusing System.Reactive;\nusing System.Reactive.Linq;\nusing System.Reflection.Metadata.Ecma335;\nusing System.Runtime.CompilerServices;\nusing System.Security.Cryptography.Pkcs;\nusing System.Security.RightsManagement;\nusing System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Markup;\nusing System.Windows.Media;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\nusing v2rayN.Tool;\nusing v2rayN.Views;\n\nusing Application = System.Windows.Application;\n\nnamespace v2rayN.ViewModels\n{\n    public class MainWindowViewModel : ReactiveObject\n    {\n        #region private prop\n\n        private CoreHandler _coreHandler;\n        private StatisticsHandler _statistics;\n        private List<ProfileItem> _lstProfile;\n        private string _subId = string.Empty;\n        private string _serverFilter = string.Empty;\n        private static Config _config;\n        private readonly PaletteHelper _paletteHelper = new();\n        private Dictionary<string, bool> _dicHeaderSort = new();\n        private Action<EViewAction> _updateView;\n        private bool IsConnected = false;\n        private string DefaultProxyMode = \"Auto\";\n        private bool IsForSettingBackLanguage = false;\n        private bool IsDelayCalculationFinished = false;\n\n        #endregion private prop\n        // It's public because we need it in MainWindow.xaml.cs\n        public NoticeHandler? _noticeHandler;\n\n        #region ObservableCollection\n\n        private IObservableCollection<ProfileItemModel> _profileItems = new ObservableCollectionExtended<ProfileItemModel>();\n        public IObservableCollection<ProfileItemModel> ProfileItems => _profileItems;\n\n        private IObservableCollection<SubItem> _subItems = new ObservableCollectionExtended<SubItem>();\n        public IObservableCollection<SubItem> SubItems => _subItems;\n\n        private IObservableCollection<RoutingItem> _routingItems = new ObservableCollectionExtended<RoutingItem>();\n        public IObservableCollection<RoutingItem> RoutingItems => _routingItems;\n\n        private IObservableCollection<ComboItem> _servers = new ObservableCollectionExtended<ComboItem>();\n        public IObservableCollection<ComboItem> Servers => _servers;\n\n        //home\n        [Reactive]\n        public ListBoxItem HomeSelectedRoutingItem { get; set; }\n\n        [Reactive]\n        public ProxyModeEnum HomeSelectedProxyMode { get; set; } = ProxyModeEnum.Loadbalance;\n        [Reactive]\n        public int SelectedProfileDelay { get; set; }\n        [Reactive]\n        public bool V2RayNPanelVisible { get; set; } = false;\n        [Reactive]\n        public string ConnectVPNLabel { get; set; } = \"Not Connected\";\n\n        [Reactive]\n        public string ConnectVPNLabelColor { get; set; } = \"#FFFF0000\";\n\n        [Reactive]\n        public double WindowWidth { get; set; }\n        [Reactive]\n        public double MaxWindowWidth { get; set; }\n\n        [Reactive]\n        public ProfileItemModel SelectedProfile { get; set; }\n\n        public IList<ProfileItemModel> SelectedProfiles { get; set; }\n\n        [Reactive]\n        public SubItem SelectedSub { get; set; }\n\n        [Reactive]\n        public SubItem SelectedMoveToGroup { get; set; }\n\n        [Reactive]\n        public RoutingItem SelectedRouting { get; set; }\n\n        [Reactive]\n        public ComboItem SelectedServer { get; set; }\n\n        [Reactive]\n        public string ServerFilter { get; set; }\n\n        [Reactive]\n        public bool BlServers { get; set; }\n\n        #endregion ObservableCollection\n\n        #region Menu\n        //home\n        public ReactiveCommand<Unit, Unit> HomeNewProfileCmd { get; }\n        public ReactiveCommand<Unit, Unit> HomeConnectCmd { get; }\n        public ReactiveCommand<Unit, Unit> HomeUpdateUsageCmd { get; }\n        public ReactiveCommand<Unit, Unit> HomeGotoProfileCmd { get; }\n        public ReactiveCommand<Unit,Unit> HomeDeleteSubCmd { get; set; }\n        public ReactiveCommand<Unit, Unit> HomeRealPingServerCmd { get; }\n\n        //servers\n        public ReactiveCommand<Unit, Unit> AddVmessServerCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> AddVlessServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> AddShadowsocksServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> AddSocksServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> AddTrojanServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> AddCustomServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> AddServerViaClipboardCmd { get; }\n        public ReactiveCommand<Unit, Unit> AddServerViaScanCmd { get; }\n\n        //servers delete\n        public ReactiveCommand<Unit, Unit> EditServerCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> RemoveServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> RemoveDuplicateServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> CopyServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> SetDefaultServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> ShareServerCmd { get; }\n\n        //servers move\n        public ReactiveCommand<Unit, Unit> MoveTopCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> MoveUpCmd { get; }\n        public ReactiveCommand<Unit, Unit> MoveDownCmd { get; }\n        public ReactiveCommand<Unit, Unit> MoveBottomCmd { get; }\n\n        //servers ping\n        public ReactiveCommand<Unit, Unit> MixedTestServerCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> PingServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> TcpingServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> RealPingServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> SpeedServerCmd { get; }\n        public ReactiveCommand<Unit, Unit> SortServerResultCmd { get; }\n\n        //servers export\n        public ReactiveCommand<Unit, Unit> Export2ClientConfigCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> Export2ShareUrlCmd { get; }\n        public ReactiveCommand<Unit, Unit> Export2SubContentCmd { get; }\n\n        //Subscription\n        public ReactiveCommand<Unit, Unit> SubSettingCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> AddSubCmd { get; }\n        public ReactiveCommand<Unit, Unit> SubUpdateCmd { get; }\n        public ReactiveCommand<Unit, Unit> SubUpdateViaProxyCmd { get; }\n        public ReactiveCommand<Unit, Unit> SubGroupUpdateCmd { get; }\n        public ReactiveCommand<Unit, Unit> SubGroupUpdateViaProxyCmd { get; }\n\n        //Setting\n        public ReactiveCommand<Unit, Unit> OptionSettingCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> RoutingSettingCmd { get; }\n        public ReactiveCommand<Unit, Unit> DNSSettingCmd { get; }\n        public ReactiveCommand<Unit, Unit> GlobalHotkeySettingCmd { get; }\n        public ReactiveCommand<Unit, Unit> RebootAsAdminCmd { get; }\n        public ReactiveCommand<Unit, Unit> ClearServerStatisticsCmd { get; }\n        public ReactiveCommand<Unit, Unit> ImportOldGuiConfigCmd { get; }\n\n        //CheckUpdate\n        public ReactiveCommand<Unit, Unit> CheckUpdateNCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> CheckUpdateV2flyCoreCmd { get; }\n        public ReactiveCommand<Unit, Unit> CheckUpdateSagerNetCoreCmd { get; }\n        public ReactiveCommand<Unit, Unit> CheckUpdateXrayCoreCmd { get; }\n        public ReactiveCommand<Unit, Unit> CheckUpdateClashCoreCmd { get; }\n        public ReactiveCommand<Unit, Unit> CheckUpdateClashMetaCoreCmd { get; }\n        public ReactiveCommand<Unit, Unit> CheckUpdateSingBoxCoreCmd { get; }\n        public ReactiveCommand<Unit, Unit> CheckUpdateGeoCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> ToggleV2rayNPanelCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> ReloadCmd { get; }\n        [Reactive]\n        public bool BlReloadEnabled { get; set; }\n\n        public ReactiveCommand<Unit, Unit> NotifyLeftClickCmd { get; }\n\n        [Reactive]\n        public Icon NotifyIcon { get; set; }\n\n        public ProxyModeEnum[] ProxyModes => (ProxyModeEnum[])Enum.GetValues(typeof(ProxyModeEnum));\n\n\n        [Reactive]\n        public ImageSource AppIcon { get; set; }\n\n        [Reactive]\n        public bool BlShowTrayTip { get; set; }\n\n        #endregion Menu\n\n        #region System Proxy\n\n        [Reactive]\n        public bool BlSystemProxyClear { get; set; }\n\n        [Reactive]\n        public bool BlSystemProxySet { get; set; }\n\n        [Reactive]\n        public bool BlSystemProxyNothing { get; set; }\n\n        [Reactive]\n        public bool BlSystemProxyPac { get; set; }\n\n        public ReactiveCommand<Unit, Unit> SystemProxyClearCmd { get; }\n        public ReactiveCommand<Unit, Unit> SystemProxySetCmd { get; }\n        public ReactiveCommand<Unit,Unit> SystemProxyToggleCmd { get; }\n        public ReactiveCommand<Unit, Unit> SystemProxyNothingCmd { get; }\n        public ReactiveCommand<Unit, Unit> SystemProxyPacCmd { get; }\n\n        [Reactive]\n        public bool BlRouting { get; set; }\n\n        [Reactive]\n        public int SystemProxySelected { get; set; }\n\n        #endregion System Proxy\n\n        #region UI\n\n\n        [Reactive]\n        public bool ConnectProgress { get; set; }\n\n        [Reactive]\n        public bool ProfileExpanded { get; set; }\n        \n        [Reactive]\n        public bool DelayProgress { get; set; } = false;\n        [Reactive]\n        public bool Loading { get; set; } = false;\n        [Reactive]\n        public string ConnectColor { get; set; } = \"#FFE0E0E0\";\n\n        [Reactive]\n        public string InboundDisplay { get; set; }\n\n        [Reactive]\n        public string InboundLanDisplay { get; set; }\n\n        [Reactive]\n        public string RunningServerDisplay { get; set; }\n\n        [Reactive]\n        public string RunningServerToolTipText { get; set; }\n\n        [Reactive]\n        public string RunningInfoDisplay { get; set; }\n\n        [Reactive]\n        public string SpeedProxyDisplay { get; set; }\n\n        [Reactive]\n        public string SpeedDirectDisplay { get; set; }\n\n        [Reactive]\n        public bool EnableTun { get; set; }\n        [Reactive]\n        public bool SysProxyState { get; set; }\n\n        [Reactive]\n        public bool ColorModeDark { get; set; }\n\n        private IObservableCollection<Swatch> _swatches = new ObservableCollectionExtended<Swatch>();\n        public IObservableCollection<Swatch> Swatches => _swatches;\n\n        [Reactive]\n        public Swatch SelectedSwatch { get; set; }\n\n        [Reactive]\n        public int CurrentFontSize { get; set; }\n\n        [Reactive]\n        public string CurrentLanguage { get; set; }\n\n        #endregion UI\n\n        #region Init\n\n        // Program will change some values when it start\n        // We will ignore that change, so we just consider user changes\n        private bool ForInitiationLanguage = true;\n        private bool ForInitiationTun = true;\n\n        public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Action<EViewAction> updateView)\n        {\n            _updateView = updateView;\n            ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);\n\n            Locator.CurrentMutable.RegisterLazySingleton(() => new NoticeHandler(snackbarMessageQueue), typeof(NoticeHandler));\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _config = LazyConfig.Instance.GetConfig();\n            //ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);\n            Init();\n\n            SelectedProfile = new();\n            SelectedSub = new();\n            SelectedMoveToGroup = new();\n            SelectedRouting = new();\n            SelectedServer = new();\n            if (_config.tunModeItem.enableTun && Utils.IsAdministrator())\n            {\n                EnableTun = true;\n            }\n            _subId = _config.subIndexId;\n\n            InitSubscriptionView();\n            RefreshRoutingsMenu();\n            RefreshServers();\n\n            // Enable Tls 1.3\n            _config.guiItem.enableSecurityProtocolTls13 = true;\n\n            this.WhenAnyValue(x => x.HomeSelectedRoutingItem).Subscribe(c => HomeSelectedRouteChanged());\n\n            this.WhenAnyValue(\n                x => x.HomeSelectedProxyMode).Subscribe(c => HomeSelectedProxyChanged());\n            var canEditRemove = this.WhenAnyValue(\n               x => x.SelectedProfile,\n               selectedSource => selectedSource != null && !selectedSource.indexId.IsNullOrEmpty());\n\n            this.WhenAnyValue(\n                x => x.SelectedSub,\n                y => y != null && !y.remarks.IsNullOrEmpty() && _subId != y.id)\n                    .Subscribe(c => SubSelectedChanged(c));\n            this.WhenAnyValue(\n                 x => x.SelectedMoveToGroup,\n                 y => y != null && !y.remarks.IsNullOrEmpty())\n                     .Subscribe(c => MoveToGroup(c));\n\n            this.WhenAnyValue(\n                x => x.SelectedRouting,\n                y => y != null && !y.remarks.IsNullOrEmpty())\n                    .Subscribe(c => RoutingSelectedChanged(c));\n\n            this.WhenAnyValue(\n              x => x.SelectedServer,\n              y => y != null && !y.Text.IsNullOrEmpty())\n                  .Subscribe(c => ServerSelectedChanged(c));\n\n            this.WhenAnyValue(\n              x => x.ServerFilter,\n              y => y != null && _serverFilter != y)\n                  .Subscribe(c => ServerFilterChanged(c));\n\n            SystemProxySelected = (int)_config.sysProxyType;\n            this.WhenAnyValue(\n              x => x.SystemProxySelected,\n              y => y >= 0)\n                  .Subscribe(c => DoSystemProxySelected(c));\n\n            this.WhenAnyValue(\n              x => x.EnableTun,\n               y => y == true)\n                  .Subscribe(c => DoEnableTun(c));\n\n            BindingUI();\n            RestoreUI();\n            //AutoHideStartup();\n\n            //home\n            HomeNewProfileCmd = ReactiveCommand.Create(() =>\n            {\n                HomeNewProfile();\n            });\n            HomeConnectCmd = ReactiveCommand.CreateFromTask(() =>\n            {\n                \n                return HomeConnect();\n            });\n            HomeUpdateUsageCmd = ReactiveCommand.Create(() =>\n            {\n                if (SelectedSub != null)\n                    HomeUpdateUsage(SelectedSub);\n            });\n            HomeGotoProfileCmd = ReactiveCommand.Create(() =>\n            {\n                HomeGotoProfile(SelectedSub.id);\n            });\n            HomeRealPingServerCmd = ReactiveCommand.CreateFromTask(() => \n            {\n                return Task.Run(async () =>\n                {\n                    // Till now, we started a server\n                    // Now we calculate real ping of the server to make sure, it's working\n                    DelayProgress = true;\n                    HomeRealPingServer(_config.indexId);\n                    // Wait for delay calculation (10 seconds)\n                    short count = 1;\n                    while (!IsDelayCalculationFinished)\n                    {\n                        // We don't want to stuck in a infinite loop\n                        if (count == 25)\n                            break;\n\n                        await Task.Delay(400).ConfigureAwait(false);\n                        count += 1;\n                    }\n                    DelayProgress = false;\n                });\n            });\n            HomeDeleteSubCmd = ReactiveCommand.Create(() =>\n            {\n                HomeDeleteSub();\n            });\n            //servers\n            AddVmessServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer(true, EConfigType.VMess);\n            });\n            AddVlessServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer(true, EConfigType.VLESS);\n            });\n            AddShadowsocksServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer(true, EConfigType.Shadowsocks);\n            });\n            AddSocksServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer(true, EConfigType.Socks);\n            });\n            AddTrojanServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer(true, EConfigType.Trojan);\n            });\n            AddCustomServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer(true, EConfigType.Custom);\n            });\n            AddServerViaClipboardCmd = ReactiveCommand.Create(() =>\n            {\n                AddServerOrSubViaClipboard();\n            });\n            AddServerViaScanCmd = ReactiveCommand.CreateFromTask(() =>\n            {\n                return ScanScreenTaskAsync();\n            });\n            //servers delete\n            EditServerCmd = ReactiveCommand.Create(() =>\n            {\n                EditServer(false, EConfigType.Custom);\n            }, canEditRemove);\n            RemoveServerCmd = ReactiveCommand.Create(() =>\n            {\n                RemoveServer();\n            }, canEditRemove);\n            RemoveDuplicateServerCmd = ReactiveCommand.Create(() =>\n            {\n                RemoveDuplicateServer();\n            });\n            CopyServerCmd = ReactiveCommand.Create(() =>\n            {\n                CopyServer();\n            }, canEditRemove);\n            SetDefaultServerCmd = ReactiveCommand.Create(() =>\n            {\n                SetDefaultServer();\n            }, canEditRemove);\n            ShareServerCmd = ReactiveCommand.Create(() =>\n            {\n                ShareServer();\n            }, canEditRemove);\n            //servers move\n            MoveTopCmd = ReactiveCommand.Create(() =>\n            {\n                MoveServer(EMove.Top);\n            }, canEditRemove);\n            MoveUpCmd = ReactiveCommand.Create(() =>\n            {\n                MoveServer(EMove.Up);\n            }, canEditRemove);\n            MoveDownCmd = ReactiveCommand.Create(() =>\n            {\n                MoveServer(EMove.Down);\n            }, canEditRemove);\n            MoveBottomCmd = ReactiveCommand.Create(() =>\n            {\n                MoveServer(EMove.Bottom);\n            }, canEditRemove);\n\n            //servers ping\n            MixedTestServerCmd = ReactiveCommand.Create(() =>\n            {\n                ServerSpeedtest(ESpeedActionType.Mixedtest);\n            });\n            PingServerCmd = ReactiveCommand.Create(() =>\n            {\n                ServerSpeedtest(ESpeedActionType.Ping);\n            }, canEditRemove);\n            TcpingServerCmd = ReactiveCommand.Create(() =>\n            {\n                ServerSpeedtest(ESpeedActionType.Tcping);\n            }, canEditRemove);\n            RealPingServerCmd = ReactiveCommand.Create(() =>\n            {\n                ServerSpeedtest(ESpeedActionType.Realping);\n            }, canEditRemove);\n            SpeedServerCmd = ReactiveCommand.Create(() =>\n            {\n                ServerSpeedtest(ESpeedActionType.Speedtest);\n            }, canEditRemove);\n            SortServerResultCmd = ReactiveCommand.Create(() =>\n            {\n                SortServer(EServerColName.delayVal.ToString());\n            });\n            //servers export\n            Export2ClientConfigCmd = ReactiveCommand.Create(() =>\n            {\n                Export2ClientConfig();\n            }, canEditRemove);\n            Export2ShareUrlCmd = ReactiveCommand.Create(() =>\n            {\n                Export2ShareUrl();\n            }, canEditRemove);\n            Export2SubContentCmd = ReactiveCommand.Create(() =>\n            {\n                Export2SubContent();\n            }, canEditRemove);\n\n            //Subscription\n            SubSettingCmd = ReactiveCommand.Create(() =>\n            {\n                SubSetting();\n            });\n            AddSubCmd = ReactiveCommand.Create(() =>\n            {\n                AddSub();\n            });\n            SubUpdateCmd = ReactiveCommand.Create(() =>\n            {\n                UpdateSubscriptionProcess(\"\", false);\n            });\n            SubUpdateViaProxyCmd = ReactiveCommand.Create(() =>\n            {\n                UpdateSubscriptionProcess(\"\", true);\n            });\n            SubGroupUpdateCmd = ReactiveCommand.Create(() =>\n            {\n                UpdateSubscriptionProcess(_subId, false);\n            });\n            SubGroupUpdateViaProxyCmd = ReactiveCommand.Create(() =>\n            {\n                UpdateSubscriptionProcess(_subId, true);\n            });\n\n            //Setting\n            OptionSettingCmd = ReactiveCommand.Create(() =>\n            {\n                OptionSetting();\n            });\n            RoutingSettingCmd = ReactiveCommand.Create(() =>\n            {\n                RoutingSetting();\n            });\n            DNSSettingCmd = ReactiveCommand.Create(() =>\n            {\n                DNSSetting();\n            });\n            GlobalHotkeySettingCmd = ReactiveCommand.Create(() =>\n            {\n                if ((new GlobalHotkeySettingWindow()).ShowDialog() == true)\n                {\n                    _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n                }\n            });\n            RebootAsAdminCmd = ReactiveCommand.Create(() =>\n            {\n                RebootAsAdmin();\n            });\n            ClearServerStatisticsCmd = ReactiveCommand.Create(() =>\n            {\n                _statistics?.ClearAllServerStatistics();\n                RefreshServers();\n            });\n            ImportOldGuiConfigCmd = ReactiveCommand.Create(() =>\n            {\n                ImportOldGuiConfig();\n            });\n\n            //CheckUpdate\n            CheckUpdateNCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateN();\n            });\n            CheckUpdateV2flyCoreCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateCore(ECoreType.v2fly_v5);\n            });\n            CheckUpdateSagerNetCoreCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateCore(ECoreType.SagerNet);\n            });\n            CheckUpdateXrayCoreCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateCore(ECoreType.Xray);\n            });\n            CheckUpdateClashCoreCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateCore(ECoreType.clash);\n            });\n            CheckUpdateClashMetaCoreCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateCore(ECoreType.clash_meta);\n            });\n            CheckUpdateSingBoxCoreCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateCore(ECoreType.sing_box);\n            });\n            CheckUpdateGeoCmd = ReactiveCommand.Create(() =>\n            {\n                CheckUpdateGeo();\n            });\n\n            ReloadCmd = ReactiveCommand.Create(() =>\n            {\n                Reload();\n            });\n\n            NotifyLeftClickCmd = ReactiveCommand.Create(() =>\n            {\n                ShowHideWindow(null);\n            });\n\n            //System proxy\n            SystemProxyClearCmd = ReactiveCommand.Create(() =>\n            {\n                UnsetSysProxy();\n            });\n            SystemProxySetCmd = ReactiveCommand.Create(() =>\n            {\n                SetSysProxy();\n            });\n            SystemProxyToggleCmd = ReactiveCommand.Create(() =>\n            {\n                ToggleSysProxy();\n            });\n            SystemProxyNothingCmd = ReactiveCommand.Create(() =>\n            {\n                SetListenerType(ESysProxyType.Unchanged);\n            });\n            SystemProxyPacCmd = ReactiveCommand.Create(() =>\n            {\n                SetListenerType(ESysProxyType.Pac);\n            });\n\n            ToggleV2rayNPanelCmd = ReactiveCommand.Create(() =>\n            {\n                ToggleV2rayPanel();\n            });\n            Global.ShowInTaskbar = true;\n\n            // Auto update sub usage every Global.DefaultUpdateSubUsageIntervalSeconds seconds\n            new Thread(delegate ()\n            {\n                while (true)\n                {\n                    if (SelectedSub != null)\n                        HomeUpdateUsage(SelectedSub);\n\n                    Thread.Sleep(TimeSpan.FromSeconds(Global.DefaultUpdateSubUsageIntervalSeconds));\n                }\n            }).Start();\n\n            // Auto update sub (profiles/servers)\n            new Thread(delegate ()\n            {\n                while (true)\n                {\n                    if (SelectedSub != null)\n                    {\n                        if (SelectedSub.enabled)\n                        {\n                            if (SelectedSub.profileUpdateInterval == 0)\n                            {\n                                bool useProxy = Utils.IsSystemProxyEnabled(_config.sysProxyType);\n                                var headers = Utils.GetUrlResponseHeader(SelectedSub.url,useProxy);\n                                var subInfo = Utils.GetSubscriptionInfoFromHeaders(headers);\n                                if (subInfo == null)\n                                    continue;\n                                if (subInfo.ProfileUpdateInterval != 0)\n                                    // Change sub item\n                                    SelectedSub.profileUpdateInterval = subInfo.ProfileUpdateInterval;\n\n                                // Edit sub item interval\n                                ConfigHandler.AddSubItem(ref _config, SelectedSub);\n                                continue;\n                            }\n                            else\n                            {\n                                if (Utils.IsSystemProxyEnabled(_config.sysProxyType))\n                                    UpdateSubscriptionProcess(SelectedSub.id, true);\n                                else\n                                    UpdateSubscriptionProcess(SelectedSub.id, false);\n                            }\n\n                        }\n                        Thread.Sleep(TimeSpan.FromHours(SelectedSub.profileUpdateInterval));\n                    }\n                    else\n                    {\n                        Thread.Sleep(700);\n                    }\n                }\n            }).Start();\n            // Connect to the default sub\n            //HomeConnect(true);\n        }\n\n        private void Init()\n        {\n            ConfigHandler.InitBuiltinRouting(ref _config);\n            ConfigHandler.InitBuiltinDNS(_config);\n            _coreHandler = new CoreHandler(_config, UpdateHandler);\n\n            if (_config.guiItem.enableStatistics)\n            {\n                _statistics = new StatisticsHandler(_config, UpdateStatisticsHandler);\n            }\n\n            MainFormHandler.Instance.UpdateTask(_config, UpdateTaskHandler);\n            MainFormHandler.Instance.RegisterGlobalHotkey(_config, OnHotkeyHandler, UpdateTaskHandler);\n\n            Reload();\n            ChangeSystemProxyStatus(_config.sysProxyType, true);\n        }\n\n        private void OnProgramStarted(object state, bool timeout)\n        {\n            Application.Current.Dispatcher.Invoke((Action)(() =>\n            {\n                ShowHideWindow(true);\n            }));\n        }\n\n        #endregion Init\n\n        #region Actions\n\n        private void UpdateHandler(bool notify, string msg)\n        {\n            _noticeHandler?.SendMessage(msg);\n        }\n\n        private void UpdateTaskHandler(bool success, string msg)\n        {\n            _noticeHandler?.SendMessage(msg);\n            if (success)\n            {\n                var indexIdOld = _config.indexId;\n                RefreshServers();\n                if (indexIdOld != _config.indexId)\n                {\n                    Reload();\n                }\n                if (_config.uiItem.enableAutoAdjustMainLvColWidth)\n                {\n                    _updateView(EViewAction.AdjustMainLvColWidth);\n                }\n            }\n            Loading = false;\n        }\n\n        private void UpdateStatisticsHandler(ServerSpeedItem update)\n        {\n            try\n            {\n                Application.Current.Dispatcher.Invoke((Action)(() =>\n                {\n                    if (!Global.ShowInTaskbar)\n                    {\n                        return;\n                    }\n\n                    SpeedProxyDisplay = string.Format(ResUI.SpeedDisplayText, Global.agentTag, Utils.HumanFy(update.proxyUp), Utils.HumanFy(update.proxyDown));\n                    SpeedDirectDisplay = string.Format(ResUI.SpeedDisplayText, Global.directTag, Utils.HumanFy(update.directUp), Utils.HumanFy(update.directDown));\n\n                    if (update.proxyUp + update.proxyDown > 0)\n                    {\n                        var second = DateTime.Now.Second;\n                        if (second % 3 == 0)\n                        {\n                            var item = _profileItems.Where(it => it.indexId == update.indexId).FirstOrDefault();\n                            if (item != null)\n                            {\n                                item.todayDown = Utils.HumanFy(update.todayDown);\n                                item.todayUp = Utils.HumanFy(update.todayUp);\n                                item.totalDown = Utils.HumanFy(update.totalDown);\n                                item.totalUp = Utils.HumanFy(update.totalUp);\n\n                                if (SelectedProfile?.indexId == item.indexId)\n                                {\n                                    var temp = Utils.DeepCopy(item);\n                                    _profileItems.Replace(item, temp);\n                                    SelectedProfile = temp;\n                                }\n                                else\n                                {\n                                    _profileItems.Replace(item, Utils.DeepCopy(item));\n                                }\n                            }\n                        }\n                    }\n                }));\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(ex.Message, ex);\n            }\n        }\n\n        private void UpdateSpeedtestHandler(string indexId, string delay, string speed)\n        {\n            Application.Current.Dispatcher.Invoke((Action)(() =>\n            {\n                SetTestResult(indexId, delay, speed);\n            }));\n        }\n\n        private void SetTestResult(string indexId, string delay, string speed)\n        {\n            if (Utils.IsNullOrEmpty(indexId))\n            {\n                _noticeHandler?.SendMessage(delay, true);\n                _noticeHandler?.Enqueue(delay);\n                return;\n            }\n            var item = _profileItems.Where(it => it.indexId == indexId).FirstOrDefault();\n            if (item != null)\n            {\n                if (!Utils.IsNullOrEmpty(delay))\n                {\n                    int.TryParse(delay, out int temp);\n                    item.delay = temp;\n                    item.delayVal = $\"{delay} {Global.DelayUnit}\";\n                }\n                if (!Utils.IsNullOrEmpty(speed))\n                {\n                    item.speedVal = $\"{speed} {Global.SpeedUnit}\";\n                }\n                _profileItems.Replace(item, Utils.DeepCopy(item));\n            }\n        }\n\n        private void OnHotkeyHandler(EGlobalHotkey e)\n        {\n            switch (e)\n            {\n                case EGlobalHotkey.ShowForm:\n                    ShowHideWindow(null);\n                    break;\n\n                case EGlobalHotkey.SystemProxyClear:\n                    SetListenerType(ESysProxyType.ForcedClear);\n                    break;\n\n                case EGlobalHotkey.SystemProxySet:\n                    SetListenerType(ESysProxyType.ForcedChange);\n                    break;\n\n                case EGlobalHotkey.SystemProxyUnchanged:\n                    SetListenerType(ESysProxyType.Unchanged);\n                    break;\n\n                case EGlobalHotkey.SystemProxyPac:\n                    SetListenerType(ESysProxyType.Pac);\n                    break;\n            }\n        }\n\n        public void PreExit(bool blWindowsShutDown)\n        {\n            Utils.SaveLog(\"PreExit Begin\");\n\n            StorageUI();\n            ConfigHandler.SaveConfig(ref _config);\n\n            //HttpProxyHandle.CloseHttpAgent(config);\n            if (blWindowsShutDown)\n            {\n                SysProxyHandle.ResetIEProxy4WindowsShutDown();\n            }\n            else\n            {\n                SysProxyHandle.UpdateSysProxy(_config, true);\n            }\n\n            ProfileExHandler.Instance.SaveTo();\n\n            _statistics?.SaveTo();\n            _statistics?.Close();\n\n            _coreHandler.CoreStop();\n            Utils.SaveLog(\"PreExit End\");\n        }\n        public void MyAppExit(bool blWindowsShutDown)\n        {\n            try\n            {\n                PreExit(blWindowsShutDown);\n            }\n            catch { }\n            finally\n            {\n                Utils.ExitSuccess();\n            }\n        }\n\n        #endregion Actions\n\n        #region Servers && Groups\n\n        public void SubSelectedChanged(bool c)\n        {\n            ProfileExpanded = false;\n            if (!c)\n            {\n                return;\n            }\n\n            string subID = GetSubIdByRemark(SelectedSub?.remarks);\n            if (subID == null)\n            {\n            //    throw new Exception(\"Selected a sub that we couldn't find its id\");\n            }\n\n            _subId = subID;\n            _config.subIndexId = _subId;\n\n            RefreshServers();\n\n            _updateView(EViewAction.ProfilesFocus);\n        }\n        // It selects appropiate server by selected sub and proxy mode\n        // It actually change config.IndexId\n        private void SelectAppropiateServer()\n        {\n            if (SelectedSub == null)\n            {\n                _noticeHandler.Enqueue(\"Please select a sub\");\n                return;\n            }\n            // User selected a proxy mode\n            if (HomeSelectedProxyMode != null)\n            {\n                \n                // Handle manual mode\n                if (HomeSelectedProxyMode == ProxyModeEnum.Manual)\n                {\n                    if (Utils.IsNullOrEmpty(_config.indexId))\n                    {\n                        //TODO: Send message to user about what happend\n                        _noticeHandler.Enqueue(\"Please select a server to connect\");\n                        ConnectColor = \"#FFE0E0E0\";\n                        ConnectProgress = false;\n                        return;\n                    }\n\n                    SetDefaultServer(_config.indexId);\n                }\n                else\n                {\n                    // Now the selected proxy mode is auto either load balance\n                    ProfileItem server = GetSelectedServer(SelectedSub.id, HomeSelectedProxyMode);\n                    if (server == null)\n                    {\n                        //TODO: Send message to user about what happend\n                        ConnectColor = \"#FFE0E0E0\";\n                        ConnectProgress = false;\n                        return;\n                    }\n                    SetDefaultServer(server.indexId);\n                }\n            }\n            // There is no selected proxy mode (we use default proxy setting)\n            else\n            {\n                ProfileItem? server = null;\n                // Just set a default mode\n                var subServers = LazyConfig.Instance.ProfileItems(SelectedSub.id);\n                if (DefaultProxyMode == \"Auto\")\n                    server = subServers.FirstOrDefault(s => s.remarks == \"Lowest Ping\");\n                else if (DefaultProxyMode == \"Load Balance\")\n                    server = subServers.FirstOrDefault(s => s.remarks == DefaultProxyMode);\n\n                if (server == null)\n                {\n                    //TODO Send message to user about what happend\n                    ConnectColor = \"#FFE0E0E0\";\n                    ConnectProgress = false;\n                    return;\n                }\n\n                SetDefaultServer(server.indexId);\n            }\n        }\n        private string? GetSubIdByRemark(string remarks)\n        {\n            foreach (SubItem item in _subItems)\n            {\n                if (item.remarks == remarks)\n                    return item.id;\n            }\n            return null;\n        }\n        private void ServerFilterChanged(bool c)\n        {\n            if (!c)\n            {\n                return;\n            }\n            _serverFilter = ServerFilter;\n            if (Utils.IsNullOrEmpty(_serverFilter))\n            {\n                RefreshServers();\n            }\n        }\n\n        public void RefreshServers()\n        {\n            List<ProfileItemModel> lstModel = LazyConfig.Instance.ProfileItems(_subId, _serverFilter);\n\n            ConfigHandler.SetDefaultServer(_config, lstModel);\n\n            List<ServerStatItem> lstServerStat = new();\n            if (_statistics != null && _statistics.Enable)\n            {\n                lstServerStat = _statistics.ServerStat;\n            }\n            var lstProfileExs = ProfileExHandler.Instance.ProfileExs;\n            lstModel = (from t in lstModel\n                        join t2 in lstServerStat on t.indexId equals t2.indexId into t2b\n                        from t22 in t2b.DefaultIfEmpty()\n                        join t3 in lstProfileExs on t.indexId equals t3.indexId into t3b\n                        from t33 in t3b.DefaultIfEmpty()\n                        select new ProfileItemModel\n                        {\n                            indexId = t.indexId,\n                            configType = t.configType,\n                            remarks = t.remarks,\n                            address = t.address,\n                            port = t.port,\n                            security = t.security,\n                            network = t.network,\n                            streamSecurity = t.streamSecurity,\n                            subid = t.subid,\n                            subRemarks = t.subRemarks,\n                            isActive = t.indexId == _config.indexId,\n                            sort = t33 == null ? 0 : t33.sort,\n                            delay = t33 == null ? 0 : t33.delay,\n                            delayVal = t33?.delay != 0 ? $\"{t33?.delay} {Global.DelayUnit}\" : string.Empty,\n                            speedVal = t33?.speed != 0 ? $\"{t33?.speed} {Global.SpeedUnit}\" : string.Empty,\n                            todayDown = t22 == null ? \"\" : Utils.HumanFy(t22.todayDown),\n                            todayUp = t22 == null ? \"\" : Utils.HumanFy(t22.todayUp),\n                            totalDown = t22 == null ? \"\" : Utils.HumanFy(t22.totalDown),\n                            totalUp = t22 == null ? \"\" : Utils.HumanFy(t22.totalUp)\n                        }).OrderBy(t => t.sort).ToList();\n            _lstProfile = Utils.FromJson<List<ProfileItem>>(Utils.ToJson(lstModel));\n\n            Application.Current.Dispatcher.Invoke((Action)(() =>\n            {\n                _profileItems.Clear();\n                _profileItems.AddRange(lstModel);\n                if (lstModel.Count > 0)\n                {\n                    var selected = lstModel.FirstOrDefault(t => t.indexId == _config.indexId);\n                    if (selected != null)\n                    {\n                        SelectedProfile = selected;\n                    }\n                    else\n                    {\n                        SelectedProfile = lstModel[0];\n                    }\n                }\n\n                RefreshServersMenu();\n\n                //display running server\n                var running = ConfigHandler.GetDefaultServer(ref _config);\n                if (running != null)\n                {\n                    var runningSummary = running.GetSummary();\n                    RunningServerDisplay = $\"{ResUI.menuServers}:{runningSummary}\";\n                    RunningServerToolTipText = runningSummary;\n                }\n                else\n                {\n                    RunningServerDisplay =\n                    RunningServerToolTipText = ResUI.CheckServerSettings;\n                }\n            }));\n        }\n\n        private void RefreshServersMenu()\n        {\n            _servers.Clear();\n            if (_lstProfile.Count > _config.guiItem.trayMenuServersLimit)\n            {\n                BlServers = false;\n                return;\n            }\n\n            BlServers = true;\n            for (int k = 0; k < _lstProfile.Count; k++)\n            {\n                ProfileItem it = _lstProfile[k];\n                string name = it.GetSummary();\n\n                var item = new ComboItem() { ID = it.indexId, Text = name };\n                _servers.Add(item);\n                if (_config.indexId == it.indexId)\n                {\n                    SelectedServer = item;\n                }\n            }\n        }\n\n        public void InitSubscriptionView()\n        {\n            _subItems.Clear();\n\n            //_subItems.Add(new SubItem { remarks = ResUI.AllGroupServers });\n            foreach (var item in LazyConfig.Instance.SubItems().OrderByDescending(t => t.sort))\n            {\n                _subItems.Add(item);\n            }\n            if (_subId != null && _subItems.FirstOrDefault(t => t.id == _subId) != null)\n            {\n                SelectedSub = _subItems.FirstOrDefault(t => t.id == _subId);\n            }\n            else\n            {\n                SelectedSub = _subItems.Count>0?_subItems[0]:null;\n            }\n            \n\n\n        }\n\n        #endregion Servers && Groups\n\n        #region Add Servers\n\n        private int GetProfileItems(out List<ProfileItem> lstSelecteds, bool latest)\n        {\n            lstSelecteds = new List<ProfileItem>();\n            if (SelectedProfiles == null || SelectedProfiles.Count <= 0)\n            {\n                return -1;\n            }\n\n            var orderProfiles = SelectedProfiles?.OrderBy(t => t.sort);\n            if (latest)\n            {\n                foreach (var profile in orderProfiles)\n                {\n                    var item = LazyConfig.Instance.GetProfileItem(profile.indexId);\n                    if (item is not null)\n                    {\n                        lstSelecteds.Add(item);\n                    }\n                }\n            }\n            else\n            {\n                lstSelecteds = Utils.FromJson<List<ProfileItem>>(Utils.ToJson(orderProfiles));\n            }\n\n            return 0;\n        }\n\n        public void EditServer(bool blNew, EConfigType eConfigType)\n        {\n            ProfileItem item;\n            if (blNew)\n            {\n                item = new()\n                {\n                    subid = _subId,\n                    configType = eConfigType,\n                    isSub = false,\n                };\n            }\n            else\n            {\n                if (Utils.IsNullOrEmpty(SelectedProfile?.indexId))\n                {\n                    return;\n                }\n                item = LazyConfig.Instance.GetProfileItem(SelectedProfile.indexId);\n                if (item is null)\n                {\n                    _noticeHandler?.Enqueue(ResUI.PleaseSelectServer);\n                    return;\n                }\n                eConfigType = item.configType;\n            }\n            bool? ret = false;\n            if (eConfigType == EConfigType.Custom)\n            {\n                ret = (new AddServer2Window(item)).ShowDialog();\n            }\n            else\n            {\n                ret = (new AddServerWindow(item)).ShowDialog();\n            }\n            if (ret == true)\n            {\n                RefreshServers();\n                if (item.indexId == _config.indexId)\n                {\n                    Reload();\n                }\n            }\n        }\n        public (int, List<string>) HomeAddServerOrSubViaClipboard(string cData)\n        {\n            Loading = true;\n            var (addedServersCount, addedSubIds) = ConfigHandler.HomeAddBatchServers(ref _config, cData, _subId, false, null);\n            if (addedSubIds.Count > 0)\n            {\n                foreach (string id in addedSubIds)\n                {\n                    \n                    //if (Utils.IsSystemProxyEnabled(_config.sysProxyType))\n                    //{\n                    //    UpdateSubscriptionProcess(id, true);\n                    //}\n                    //else\n                    //{\n                    //TODO: we should first get the sub link without proxy if not working use proxy\n                        UpdateSubscriptionProcess(id, false);\n                    //}\n                    \n                }\n            }\n            else { \n                Loading = false; \n            }\n            return (addedServersCount, addedSubIds);\n        }\n        public void AddServerOrSubViaClipboard()\n        {\n            \n            string clipboardData = Utils.GetClipboardData();\n            HomeAddServerOrSubViaClipboard(clipboardData);\n            return;\n            int ret = ConfigHandler.AddBatchServers(ref _config, clipboardData, _subId, false);\n            if (ret > 0)\n            {\n                InitSubscriptionView();\n                RefreshServers();\n                _noticeHandler?.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));\n\n                // This update all subscriptions\n                // TODO: update just added sub, if was a sub added\n                UpdateSubscriptionProcess(\"\", Utils.IsSystemProxyEnabled(_config.sysProxyType));\n            }\n        }\n        public void AddServerOrSubViaDeepLink(string url)\n        {\n            HomeAddServerOrSubViaClipboard(url);\n            return;\n            int ret = ConfigHandler.AddBatchServers(ref _config, url, _subId, false);\n            if (ret > 0)\n            {\n                InitSubscriptionView();\n                RefreshServers();\n                _noticeHandler?.Enqueue(string.Format(ResUI.SuccessfullyImportedServerViaClipboard, ret));\n\n                // This update all subscriptions\n                // TODO: update just added sub, if was a sub added\n                UpdateSubscriptionProcess(\"\", Utils.IsSystemProxyEnabled(_config.sysProxyType));\n            }\n        }\n        public void AddServersViaDeeplink(string servers_link)\n        {\n\n        }\n        public void AddSubViaDeeplink(string sub_url)\n        {\n\n        }\n        public void AddSubAndServerViaDeeplink(string data)\n        {\n\n        }\n        public async Task ScanScreenTaskAsync()\n        {\n            ShowHideWindow(false);\n\n            var dpiXY = Utils.GetDpiXY(Application.Current.MainWindow);\n            string result = await Task.Run(() =>\n            {\n                return Utils.ScanScreen(dpiXY.Item1, dpiXY.Item2);\n            });\n\n            ShowHideWindow(true);\n\n            if (Utils.IsNullOrEmpty(result))\n            {\n                _noticeHandler?.Enqueue(ResUI.NoValidQRcodeFound);\n            }\n            else\n            {\n                int ret = ConfigHandler.AddBatchServers(ref _config, result, _subId, false);\n                if (ret > 0)\n                {\n                    InitSubscriptionView();\n                    RefreshServers();\n                    _noticeHandler?.Enqueue(ResUI.SuccessfullyImportedServerViaScan);\n                }\n            }\n        }\n\n        public void RemoveServer()\n        {\n            if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0)\n            {\n                return;\n            }\n\n            if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)\n            {\n                return;\n            }\n            var exists = lstSelecteds.Exists(t => t.indexId == _config.indexId);\n\n            ConfigHandler.RemoveServer(_config, lstSelecteds);\n            _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n\n            RefreshServers();\n            if (exists)\n            {\n                Reload();\n            }\n        }\n\n        private void RemoveDuplicateServer()\n        {\n            var tuple = ConfigHandler.DedupServerList(_config, _subId);\n            RefreshServers();\n            Reload();\n            _noticeHandler?.Enqueue(string.Format(ResUI.RemoveDuplicateServerResult, tuple.Item1, tuple.Item2));\n        }\n\n        private void CopyServer()\n        {\n            if (GetProfileItems(out List<ProfileItem> lstSelecteds, false) < 0)\n            {\n                return;\n            }\n            if (ConfigHandler.CopyServer(ref _config, lstSelecteds) == 0)\n            {\n                RefreshServers();\n                _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n            }\n        }\n\n        public void SetDefaultServer()\n        {\n            if (Utils.IsNullOrEmpty(SelectedProfile?.indexId))\n            {\n                return;\n            }\n            SetDefaultServer(SelectedProfile.indexId);\n        }\n\n        private void SetDefaultServer(string indexId)\n        {\n            if (Utils.IsNullOrEmpty(indexId))\n            {\n                return;\n            }\n            if (indexId == _config.indexId)\n            {\n                return;\n            }\n            var item = LazyConfig.Instance.GetProfileItem(indexId);\n            if (item is null)\n            {\n                _noticeHandler?.Enqueue(ResUI.PleaseSelectServer);\n                return;\n            }\n\n            if (ConfigHandler.SetDefaultServerIndex(ref _config, indexId) == 0)\n            {\n                RefreshServers();\n                Reload();\n            }\n        }\n\n        private void ServerSelectedChanged(bool c)\n        {\n            if (!c)\n            {\n                return;\n            }\n            if (SelectedServer == null)\n            {\n                return;\n            }\n            if (Utils.IsNullOrEmpty(SelectedServer.ID))\n            {\n                return;\n            }\n            SetDefaultServer(SelectedServer.ID);\n        }\n\n        public async void ShareServer()\n        {\n            var item = LazyConfig.Instance.GetProfileItem(SelectedProfile.indexId);\n            if (item is null)\n            {\n                _noticeHandler?.Enqueue(ResUI.PleaseSelectServer);\n                return;\n            }\n            string url = ShareHandler.GetShareUrl(item);\n            if (Utils.IsNullOrEmpty(url))\n            {\n                return;\n            }\n            var img = QRCodeHelper.GetQRCode(url);\n            var dialog = new QrcodeView()\n            {\n                imgQrcode = { Source = img },\n                txtContent = { Text = url },\n            };\n\n            await DialogHost.Show(dialog, \"RootDialog\");\n        }\n\n        public void SortServer(string colName)\n        {\n            if (Utils.IsNullOrEmpty(colName))\n            {\n                return;\n            }\n\n            _dicHeaderSort.TryAdd(colName, true);\n            _dicHeaderSort.TryGetValue(colName, out bool asc);\n            if (ConfigHandler.SortServers(ref _config, _subId, colName, asc) != 0)\n            {\n                return;\n            }\n            _dicHeaderSort[colName] = !asc;\n            RefreshServers();\n        }\n\n        public void TestServerAvailability()\n        {\n            var item = ConfigHandler.GetDefaultServer(ref _config);\n            if (item == null || item.configType == EConfigType.Custom)\n            {\n                return;\n            }\n            (new UpdateHandle()).RunAvailabilityCheck((bool success, string msg) =>\n            {\n                _noticeHandler?.SendMessage(msg, true);\n                Application.Current.Dispatcher.Invoke((Action)(() =>\n                {\n                    if (!Global.ShowInTaskbar)\n                    {\n                        return;\n                    }\n                    RunningInfoDisplay = msg;\n                }));\n            });\n        }\n\n        //move server\n        private void MoveToGroup(bool c)\n        {\n            if (!c)\n            {\n                return;\n            }\n\n            if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0)\n            {\n                return;\n            }\n\n            ConfigHandler.MoveToGroup(_config, lstSelecteds, SelectedMoveToGroup.id);\n            _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n\n            RefreshServers();\n            SelectedMoveToGroup = new();\n            //Reload();\n        }\n\n        public void MoveServer(EMove eMove)\n        {\n            var item = _lstProfile.FirstOrDefault(t => t.indexId == SelectedProfile.indexId);\n            if (item is null)\n            {\n                _noticeHandler?.Enqueue(ResUI.PleaseSelectServer);\n                return;\n            }\n\n            int index = _lstProfile.IndexOf(item);\n            if (index < 0)\n            {\n                return;\n            }\n            if (ConfigHandler.MoveServer(ref _config, ref _lstProfile, index, eMove) == 0)\n            {\n                RefreshServers();\n            }\n        }\n\n        public void MoveServerTo(int startIndex, ProfileItemModel targetItem)\n        {\n            var targetIndex = _profileItems.IndexOf(targetItem);\n            if (startIndex >= 0 && targetIndex >= 0 && startIndex != targetIndex)\n            {\n                if (ConfigHandler.MoveServer(ref _config, ref _lstProfile, startIndex, EMove.Position, targetIndex) == 0)\n                {\n                    RefreshServers();\n                }\n            }\n        }\n\n        public void ServerSpeedtest(ESpeedActionType actionType)\n        {\n            if (actionType == ESpeedActionType.Mixedtest)\n            {\n                SelectedProfiles = _profileItems;\n            }\n            if (GetProfileItems(out List<ProfileItem> lstSelecteds, false) < 0)\n            {\n                return;\n            }\n            //ClearTestResult();\n            new SpeedtestHandler(_config, _coreHandler, lstSelecteds, actionType, UpdateSpeedtestHandler);\n        }\n\n        private void Export2ClientConfig()\n        {\n            var item = LazyConfig.Instance.GetProfileItem(SelectedProfile.indexId);\n            if (item is null)\n            {\n                _noticeHandler?.Enqueue(ResUI.PleaseSelectServer);\n                return;\n            }\n            MainFormHandler.Instance.Export2ClientConfig(item, _config);\n        }\n\n        public void Export2ShareUrl()\n        {\n            if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0)\n            {\n                return;\n            }\n\n            StringBuilder sb = new();\n            foreach (var it in lstSelecteds)\n            {\n                string url = ShareHandler.GetShareUrl(it);\n                if (Utils.IsNullOrEmpty(url))\n                {\n                    continue;\n                }\n                sb.Append(url);\n                sb.AppendLine();\n            }\n            if (sb.Length > 0)\n            {\n                Utils.SetClipboardData(sb.ToString());\n                _noticeHandler?.SendMessage(ResUI.BatchExportURLSuccessfully);\n            }\n        }\n\n        private void Export2SubContent()\n        {\n            if (GetProfileItems(out List<ProfileItem> lstSelecteds, true) < 0)\n            {\n                return;\n            }\n\n            StringBuilder sb = new();\n            foreach (var it in lstSelecteds)\n            {\n                string? url = ShareHandler.GetShareUrl(it);\n                if (Utils.IsNullOrEmpty(url))\n                {\n                    continue;\n                }\n                sb.Append(url);\n                sb.AppendLine();\n            }\n            if (sb.Length > 0)\n            {\n                Utils.SetClipboardData(Utils.Base64Encode(sb.ToString()));\n                _noticeHandler?.SendMessage(ResUI.BatchExportSubscriptionSuccessfully);\n            }\n        }\n\n        #endregion Add Servers\n\n        #region Subscription\n\n        private void SubSetting()\n        {\n            if ((new SubSettingWindow()).ShowDialog() == true)\n            {\n                // Update view\n                InitSubscriptionView();\n                SubSelectedChanged(true);\n\n                // Update Subscription after add\n                SubItem latestSubItem = LazyConfig.Instance.GetLastSubItem();\n                if (latestSubItem != null)\n                {\n                    UpdateSubscriptionProcess(latestSubItem.id, true);\n                }\n            }\n        }\n\n        private void AddSub()\n        {\n            SubItem item = new();\n            var ret = (new SubEditWindow(item)).ShowDialog();\n            if (ret == true)\n            {\n                // Update view\n                InitSubscriptionView();\n                SubSelectedChanged(true);\n\n                // Update Subscription after add\n                SubItem latestSubItem = LazyConfig.Instance.GetLastSubItem();\n                if (latestSubItem != null)\n                {\n                    UpdateSubscriptionProcess(latestSubItem.id, true);\n                }\n            }\n        }\n\n\n        public void UpdateSubscriptionProcess(string subId, bool blProxy)\n        {\n            (new UpdateHandle()).UpdateSubscriptionProcess(_config, subId, blProxy, UpdateTaskHandler);\n        }\n\n        #endregion Subscription\n\n        #region Setting\n\n        private void OptionSetting()\n        {\n            var ret = (new OptionSettingWindow()).ShowDialog();\n            if (ret == true)\n            {\n                //RefreshServers();\n                Reload();\n            }\n        }\n\n        private void RoutingSetting()\n        {\n            var ret = (new RoutingSettingWindow()).ShowDialog();\n            if (ret == true)\n            {\n                ConfigHandler.InitBuiltinRouting(ref _config);\n                RefreshRoutingsMenu();\n                //RefreshServers();\n                Reload();\n            }\n        }\n\n        private void DNSSetting()\n        {\n            var ret = (new DNSSettingWindow()).ShowDialog();\n            if (ret == true)\n            {\n                Reload();\n            }\n        }\n\n        private void RebootAsAdmin()\n        {\n            ProcessStartInfo startInfo = new()\n            {\n                UseShellExecute = true,\n                Arguments = Global.RebootAs,\n                WorkingDirectory = Utils.StartupPath(),\n                FileName = Utils.GetExePath(),\n                Verb = \"runas\",\n            };\n            try\n            {\n                Process.Start(startInfo);\n                MyAppExit(false);\n            }\n            catch { }\n        }\n\n        private void ImportOldGuiConfig()\n        {\n            OpenFileDialog fileDialog = new()\n            {\n                Multiselect = false,\n                Filter = \"guiNConfig|*.json|All|*.*\"\n            };\n            if (fileDialog.ShowDialog() != true)\n            {\n                return;\n            }\n            string fileName = fileDialog.FileName;\n            if (Utils.IsNullOrEmpty(fileName))\n            {\n                return;\n            }\n\n            var ret = ConfigHandler.ImportOldGuiConfig(ref _config, fileName);\n            if (ret == 0)\n            {\n                RefreshRoutingsMenu();\n                InitSubscriptionView();\n                RefreshServers();\n                Reload();\n                UI.Show(ResUI.OperationSuccess);\n            }\n            else\n            {\n                _noticeHandler.Enqueue(ResUI.OperationFailed);\n            }\n        }\n\n        #endregion Setting\n\n        #region CheckUpdate\n\n        private void CheckUpdateN()\n        {\n            void _updateUI(bool success, string msg)\n            {\n                _noticeHandler?.SendMessage(msg);\n                if (success)\n                {\n                    MyAppExit(false);\n                }\n            }\n            (new UpdateHandle()).CheckUpdateGuiN(_config, _updateUI, _config.guiItem.checkPreReleaseUpdate);\n        }\n\n        private void CheckUpdateCore(ECoreType type)\n        {\n            void _updateUI(bool success, string msg)\n            {\n                _noticeHandler?.SendMessage(msg);\n                if (success)\n                {\n                    CloseV2ray();\n\n                    string fileName = Utils.GetTempPath(Utils.GetDownloadFileName(msg));\n                    string toPath = Utils.GetBinPath(\"\", type);\n\n                    FileManager.ZipExtractToFile(fileName, toPath, _config.guiItem.ignoreGeoUpdateCore ? \"geo\" : \"\");\n\n                    _noticeHandler?.SendMessage(ResUI.MsgUpdateV2rayCoreSuccessfullyMore);\n\n                    Reload();\n\n                    _noticeHandler?.SendMessage(ResUI.MsgUpdateV2rayCoreSuccessfully);\n\n                    if (File.Exists(fileName))\n                    {\n                        File.Delete(fileName);\n                    }\n                }\n            }\n            (new UpdateHandle()).CheckUpdateCore(type, _config, _updateUI, _config.guiItem.checkPreReleaseUpdate);\n        }\n\n        private void CheckUpdateGeo()\n        {\n            (new UpdateHandle()).UpdateGeoFileAll(_config, UpdateTaskHandler);\n        }\n\n        #endregion CheckUpdate\n\n        #region v2ray job\n\n        public void Reload()\n        {\n            _ = LoadV2ray();\n        }\n\n        private async Task LoadV2ray()\n        {\n            Application.Current.Dispatcher.Invoke((Action)(() =>\n            {\n                BlReloadEnabled = false;\n            }));\n\n            await Task.Run(() =>\n            {\n                _coreHandler.LoadCore();\n\n                //ConfigHandler.SaveConfig(ref _config, false);\n\n                ChangeSystemProxyStatus(_config.sysProxyType, false);\n            });\n\n            TestServerAvailability();\n\n            Application.Current.Dispatcher.Invoke((Action)(() =>\n            {\n                BlReloadEnabled = true;\n            }));\n            ServerSpeedtest(ESpeedActionType.Realping);\n        }\n\n        private void CloseV2ray()\n        {\n            ConfigHandler.SaveConfig(ref _config, false);\n\n            ChangeSystemProxyStatus(ESysProxyType.ForcedClear, false);\n\n            _coreHandler.CoreStop();\n        }\n\n        #endregion v2ray job\n\n        #region System proxy and Routings\n\n        public void SetListenerType(ESysProxyType type)\n        {\n            if (_config.sysProxyType == type)\n            {\n                return;\n            }\n            _config.sysProxyType = type;\n            ChangeSystemProxyStatus(type, true);\n\n            SystemProxySelected = (int)_config.sysProxyType;\n            ConfigHandler.SaveConfig(ref _config, false);\n        }\n\n        private void ChangeSystemProxyStatus(ESysProxyType type, bool blChange)\n        {\n            SysProxyHandle.UpdateSysProxy(_config, false);\n            _noticeHandler?.SendMessage(ResUI.TipChangeSystemProxy, true);\n\n            Application.Current.Dispatcher.Invoke((Action)(() =>\n            {\n                BlSystemProxyClear = (type == ESysProxyType.ForcedClear);\n                BlSystemProxySet = (type == ESysProxyType.ForcedChange);\n                BlSystemProxyNothing = (type == ESysProxyType.Unchanged);\n                BlSystemProxyPac = (type == ESysProxyType.Pac);\n\n                InboundDisplayStaus();\n\n                if (blChange)\n                {\n                    NotifyIcon = MainFormHandler.Instance.GetNotifyIcon(_config);\n                    AppIcon = MainFormHandler.Instance.GetAppIcon(_config);\n                }\n                if (BlSystemProxySet || BlSystemProxyPac)\n                {\n                    SysProxyState = true;\n                }\n                else\n                {\n                    SysProxyState = false;\n                }\n            }));\n        }\n\n        private void RefreshRoutingsMenu()\n        {\n            _routingItems.Clear();\n            if (!_config.routingBasicItem.enableRoutingAdvanced)\n            {\n                BlRouting = false;\n                return;\n            }\n\n            BlRouting = true;\n            var routings = LazyConfig.Instance.RoutingItems();\n            foreach (var item in routings)\n            {\n                _routingItems.Add(item);\n                if (item.id == _config.routingBasicItem.routingIndexId)\n                {\n                    SelectedRouting = item;\n                }\n            }\n        }\n        private void RoutingSelectedChanged(bool c)\n        {\n            if (!c)\n            {\n                return;\n            }\n\n            if (SelectedRouting == null)\n            {\n                return;\n            }\n\n            var item = LazyConfig.Instance.GetRoutingItem(SelectedRouting?.id);\n            if (item is null)\n            {\n                return;\n            }\n            if (_config.routingBasicItem.routingIndexId == item.id)\n            {\n                return;\n            }\n\n            if (ConfigHandler.SetDefaultRouting(ref _config, item) == 0)\n            {\n                _noticeHandler?.SendMessage(ResUI.TipChangeRouting, true);\n                Reload();\n            }\n        }\n\n        private void DoSystemProxySelected(bool c)\n        {\n            if (!c)\n            {\n                return;\n            }\n            if (_config.sysProxyType == (ESysProxyType)SystemProxySelected)\n            {\n                return;\n            }\n            SetListenerType((ESysProxyType)SystemProxySelected);\n        }\n        private void SetSysProxy()\n        {\n            SetListenerType(ESysProxyType.ForcedChange);\n            SysProxyState = true;\n            _config.sysProxyType= ESysProxyType.ForcedChange;\n        }\n        private void UnsetSysProxy()\n        {\n            SetListenerType(ESysProxyType.ForcedClear);\n            SysProxyState = false;\n            _config.sysProxyType = ESysProxyType.ForcedClear;\n        }\n        public void ToggleSysProxy()\n        {\n            // The \"SysProxyState\" variable will be change in the UI\n            // that means when it's off and user clicks on that we will have \"SysProxyState\" true, cause it was changed when user clicked\n            if (SysProxyState)\n            {\n                SetSysProxy();\n            }\n            else\n            {\n                UnsetSysProxy();\n            }\n        }\n\n        private void DoEnableTun(bool c)\n        {\n            // If it's for initiation, we ignore (user didn't change the value)\n            if (ForInitiationTun)\n            {\n                ForInitiationTun = false;\n                return;\n                Reload();\n            }\n\n            if (Utils.IsAdministrator())\n            {\n                if (_config.tunModeItem.enableTun != EnableTun)\n                {\n                    _config.tunModeItem.enableTun = EnableTun;\n                }\n                TunModeSwitch();\n            }\n\n        }\n\n        private void TunModeSwitch()\n        {\n            if (EnableTun)\n            {\n                TunHandler.Instance.Start();\n            }\n            else\n            {\n                TunHandler.Instance.Stop();\n            }\n        }\n\n        #endregion System proxy and Routings\n\n        #region UI\n\n        public void ShowHideWindow(bool? blShow)\n        {\n            var bl = blShow ?? !Global.ShowInTaskbar;\n            if (bl)\n            {\n                //Application.Current.MainWindow.ShowInTaskbar = true;\n                Application.Current.MainWindow.Show();\n                if (Application.Current.MainWindow.WindowState == WindowState.Minimized)\n                {\n                    Application.Current.MainWindow.WindowState = WindowState.Normal;\n                }\n                Application.Current.MainWindow.Activate();\n                Application.Current.MainWindow.Focus();\n            }\n            else\n            {\n                Application.Current.MainWindow.Hide();\n                //Application.Current.MainWindow.ShowInTaskbar = false;\n                //IntPtr windowHandle = new WindowInteropHelper(Application.Current.MainWindow).Handle;\n                //Utils.RegWriteValue(Global.MyRegPath, Utils.WindowHwndKey, Convert.ToString((long)windowHandle));\n            }\n            Global.ShowInTaskbar = bl;\n        }\n\n        private void RestoreUI()\n        {\n            ModifyTheme(_config.uiItem.colorModeDark);\n\n            if (!_config.uiItem.colorPrimaryName.IsNullOrEmpty())\n            {\n                var swatch = new SwatchesProvider().Swatches.FirstOrDefault(t => t.Name == _config.uiItem.colorPrimaryName);\n                if (swatch != null\n                   && swatch.ExemplarHue != null\n                   && swatch.ExemplarHue?.Color != null)\n                {\n                    ChangePrimaryColor(swatch.ExemplarHue.Color);\n                }\n            }\n        }\n\n        private void StorageUI()\n        {\n        }\n\n        private void BindingUI()\n        {\n            ColorModeDark = _config.uiItem.colorModeDark;\n            _swatches.AddRange(new SwatchesProvider().Swatches);\n            if (!_config.uiItem.colorPrimaryName.IsNullOrEmpty())\n            {\n                SelectedSwatch = _swatches.FirstOrDefault(t => t.Name == _config.uiItem.colorPrimaryName);\n            }\n            CurrentFontSize = _config.uiItem.currentFontSize;\n            CurrentLanguage = _config.uiItem.currentLanguage;\n            BlShowTrayTip = _config.uiItem.showTrayTip;\n\n            this.WhenAnyValue(\n                  x => x.ColorModeDark,\n                  y => y == true)\n                      .Subscribe(c =>\n                      {\n                          \n                              if (_config.uiItem.colorModeDark != ColorModeDark)\n                              {\n                                  _config.uiItem.colorModeDark = ColorModeDark;\n                                  ModifyTheme(ColorModeDark);\n                                  ConfigHandler.SaveConfig(ref _config);\n                              }\n                          \n                      });\n\n            this.WhenAnyValue(\n              x => x.SelectedSwatch,\n              y => y != null && !y.Name.IsNullOrEmpty())\n                 .Subscribe(c =>\n                 {\n                     if (SelectedSwatch == null\n                     || SelectedSwatch.Name.IsNullOrEmpty()\n                     || SelectedSwatch.ExemplarHue == null\n                     || SelectedSwatch.ExemplarHue?.Color == null)\n                     {\n                         return;\n                     }\n                     if (_config.uiItem.colorPrimaryName != SelectedSwatch?.Name)\n                     {\n                         _config.uiItem.colorPrimaryName = SelectedSwatch?.Name;\n                         ChangePrimaryColor(SelectedSwatch.ExemplarHue.Color);\n                         ConfigHandler.SaveConfig(ref _config);\n                     }\n                 });\n\n            this.WhenAnyValue(\n               x => x.CurrentFontSize,\n               y => y > 0)\n                  .Subscribe(c =>\n                  {\n                      if (CurrentFontSize >= Global.MinFontSize)\n                      {\n                          _config.uiItem.currentFontSize = CurrentFontSize;\n                          double size = (long)CurrentFontSize;\n                          Application.Current.Resources[\"StdFontSize\"] = size;\n                          Application.Current.Resources[\"StdFontSize1\"] = size + 1;\n                          Application.Current.Resources[\"StdFontSize2\"] = size + 2;\n                          Application.Current.Resources[\"StdFontSizeMsg\"] = size - 1;\n\n                          ConfigHandler.SaveConfig(ref _config);\n                      }\n                  });\n\n            this.WhenAnyValue(\n             x => x.CurrentLanguage,\n             y => y != null && !y.IsNullOrEmpty())\n                .Subscribe(c =>\n                {\n                    if (!Utils.IsNullOrEmpty(CurrentLanguage))\n                    {\n                        if (ForInitiationLanguage)\n                        {\n                            ForInitiationLanguage = false;\n                        }\n                        else\n                        {\n                            if (IsForSettingBackLanguage)\n                            {\n                                IsForSettingBackLanguage = false;\n                                return;\n                            }\n\n                            //var userRes = UI.ShowYesNo(ResUI.MsgProgramNeedsRestarting);\n                            //if (userRes == DialogResult.Yes)\n                            {\n                                Thread.CurrentThread.CurrentUICulture = new(CurrentLanguage);\n                                CultureInfo.DefaultThreadCurrentUICulture = new(_config.uiItem.currentLanguage);\n                                _config.uiItem.currentLanguage = CurrentLanguage;\n                                ConfigHandler.SaveConfig(ref _config);\n\n                                // Restart program\n                                // PreExit(true);\n                                //Utils.RestartProgram();\n                                Thread.CurrentThread.CurrentUICulture = new(_config.uiItem.currentLanguage);\n                                var newWindow = new MainWindow();\n\n                                // copy over any necessary properties from the old window\n                                newWindow.DataContext = this;\n\n                                // show the new window and close the old window\n                                var old = Application.Current.MainWindow;\n\n                                newWindow.Show();\n                                newWindow.WindowState = WindowState.Minimized;\n                                newWindow.WindowState = WindowState.Normal;\n                                newWindow.Activate();\n                                newWindow.Topmost = true;\n                                newWindow.Topmost = false;\n                                newWindow.Focus();\n\n                                newWindow.Show();\n                                old.Close();\n                                Application.Current.MainWindow = newWindow;\n\n                                // Refresh subs information when language changed\n                                InitSubscriptionView();\n                                // Exit the current instance of the application\n                                //Application.Current.Shutdown();\n\n                            }\n                            /*else\n                            {\n                                //TODO: it doesn't setting back language, in fact it does for variable but in ui doesn't\n                                IsForSettingBackLanguage = true;\n                                CurrentLanguage = _config.uiItem.currentLanguage;\n                            }*/\n                        }\n\n                    }\n                });\n        }\n\n        public void InboundDisplayStaus()\n        {\n            StringBuilder sb = new();\n            sb.Append($\"[{Global.InboundSocks}:{LazyConfig.Instance.GetLocalPort(Global.InboundSocks)}]\");\n            sb.Append(\" | \");\n            //if (_config.sysProxyType == ESysProxyType.ForcedChange)\n            //{\n            //    sb.Append($\"[{Global.InboundHttp}({ResUI.SystemProxy}):{LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}]\");\n            //}\n            //else\n            //{\n            sb.Append($\"[{Global.InboundHttp}:{LazyConfig.Instance.GetLocalPort(Global.InboundHttp)}]\");\n            //}\n            InboundDisplay = $\"{ResUI.LabLocal}:{sb}\";\n\n            if (_config.inbound[0].allowLANConn)\n            {\n                if (_config.inbound[0].newPort4LAN)\n                {\n                    StringBuilder sb2 = new();\n                    sb2.Append($\"[{Global.InboundSocks}:{LazyConfig.Instance.GetLocalPort(Global.InboundSocks2)}]\");\n                    sb2.Append(\" | \");\n                    sb2.Append($\"[{Global.InboundHttp}:{LazyConfig.Instance.GetLocalPort(Global.InboundHttp2)}]\");\n                    InboundLanDisplay = $\"{ResUI.LabLAN}:{sb2}\";\n                }\n                else\n                {\n                    InboundLanDisplay = $\"{ResUI.LabLAN}:{sb}\";\n                }\n            }\n            else\n            {\n                InboundLanDisplay = $\"{ResUI.LabLAN}:None\";\n            }\n        }\n\n        public void ModifyTheme(bool isDarkTheme)\n        {\n            var theme = _paletteHelper.GetTheme();\n\n            theme.SetBaseTheme(isDarkTheme ? Theme.Dark : Theme.Light);\n            _paletteHelper.SetTheme(theme);\n\n            Utils.SetDarkBorder(Application.Current.MainWindow, isDarkTheme);\n        }\n\n        public void ChangePrimaryColor(System.Windows.Media.Color color)\n        {\n            var theme = _paletteHelper.GetTheme();\n\n            theme.PrimaryLight = new ColorPair(color.Lighten());\n            theme.PrimaryMid = new ColorPair(color);\n            theme.PrimaryDark = new ColorPair(color.Darken());\n\n            _paletteHelper.SetTheme(theme);\n        }\n\n        private void AutoHideStartup()\n        {\n            if (_config.uiItem.autoHideStartup)\n            {\n                Observable.Range(1, 1)\n                 .Delay(TimeSpan.FromSeconds(2))\n                 .Subscribe(x =>\n                 {\n                     Application.Current.Dispatcher.Invoke(() =>\n                     {\n                         ShowHideWindow(false);\n                     });\n                 });\n            }\n        }\n\n        #endregion UI\n\n        #region Home\n        public void HomeNewProfile()\n        {\n            // Get clipboard data\n            string? cData = Utils.GetClipboardData();\n            if (cData == null)\n            {\n                // TODO @everyone: translate this response\n                UI.ShowError(\"There's no config/url/link\");\n            }\n            else\n            {\n                var (addedServersCount, addedSubsIds) = HomeAddServerOrSubViaClipboard(cData);\n                // If nothing added, we show some error to user\n                if (addedServersCount == 0 && (addedSubsIds == null || addedSubsIds.Count < 1))\n                {\n                    // TODO @everyone: translate this response\n                    UI.ShowError(\"There's invalid config/url/link\");\n                }\n                else\n                {\n                    string msg = \"\";\n                    if (addedServersCount > 0)\n                    {\n                        msg = $\"Added servers: {addedServersCount}\";\n                    }\n                    if (addedSubsIds?.Count > 0)\n                    {\n                        SelectedSub= LazyConfig.Instance.GetSubItem(addedSubsIds[0]);\n                        msg += $\"\\nAdded subscription: {addedSubsIds?.Count}\";\n                    }\n                    UI.Show(msg);\n                }\n\n            }\n        }\n        public void HomeUpdateUsage(SubItem sub)\n        {\n            if (sub != null)\n            {\n                var headers = Utils.GetUrlResponseHeader(sub.url,false);\n                if (headers != null)\n                {\n                    var subInfo = Utils.GetSubscriptionInfoFromHeaders(headers);\n                    if (subInfo != null)\n                    {\n                        sub.upload = subInfo.Upload;\n                        sub.download = subInfo.Download;\n                        sub.total = subInfo.Total;\n                        sub.expireDate = subInfo.ExpireDate;\n                        sub.remaningExpireDays = sub.DaysLeftToExpire();\n                        sub.UsedDataGB = sub.UsedDataGigaBytes();\n                        sub.TotalDataGB = sub.TotalDataGigaBytes();\n                        sub.profileWebPageUrl = subInfo.ProfileWebPageUrl;\n\n                        // Replace the sub with new information\n                        if (ConfigHandler.AddSubItem(ref _config, sub,true) == 0)\n                        {\n                            //successed\n                        }\n                        else\n                        {\n                            //failed\n                        }\n                    }\n                }\n            }\n        }\n        public async Task HomeConnect(bool forceConnect = false)\n        {\n            //var result = DialogHost.Show(\"hi!\", \"RootDialog\");\n            \n            \n            if (SelectedSub == null)\n            {\n                _noticeHandler.Enqueue(\"Please select a sub\");\n                return;\n            }\n            // It's disconnected or it should be connected again\n            if (forceConnect || !IsConnected)\n            {\n\n                // Change connectVPN button color\n                ConnectProgress = true;\n                ConnectColor = \"#eab676\";\n                SelectAppropiateServer();\n                //await HomeRealPingServer(_config.indexId);\n                // Till now, we started a server\n                // Now we calculate real ping of the server to make sure, it's working\n                \n                // If user selected load balance/auto we can't get \"real ping\" (i don't know why?!)\n                // So, Insted of \"real ping\", we just send a request and check the http response status\n                if (HomeSelectedProxyMode != null &&\n                    \n                    (HomeSelectedProxyMode== ProxyModeEnum.Smart || HomeSelectedProxyMode==ProxyModeEnum.Loadbalance))\n                {\n                    DelayProgress = true;\n                    ConnectVPNLabel = ResUI.HomeConnecting;\n\n                    bool useProxy = Utils.IsSystemProxyEnabled(_config.sysProxyType);\n                    var startTime = DateTime.Now;\n                    var isStatusCode204 = await Utils.IsUrlStatusCode204(Global.SpeedPingTestUrlCloadFlare,useProxy);\n                    var delay = (DateTime.Now - startTime).Milliseconds;\n                    // Check returned status code\n                    if (isStatusCode204)\n                    {\n                        // Set server delay\n                        SelectedProfileDelay = delay;\n                        // The server works\n                        DelayProgress = false;\n                        ConnectProgress = false;\n                        ConnectVPNLabelColor = \"#7CFC0000\";\n                        ConnectVPNLabel = ResUI.HomeConnected;\n                        ConnectColor = \"#33d91a\";\n                        IsConnected = true;\n                        SetSysProxy();\n                        return;\n                    }\n                    else\n                    {\n                        SelectedProfileDelay = -1;\n                        // The server doesn't work\n                        DelayProgress = false;\n                        ConnectProgress = false;\n                        ConnectColor = \"#d6003b\";\n                        ConnectVPNLabel = ResUI.HomeNotConnected;\n                        IsConnected = false;\n                        return;\n                    }\n\n                }\n                // the \"Manual\" mode is selected; neither \"Auto\" or \"Load Balance\"\n                else\n                {\n                    DelayProgress = true;\n                    HomeRealPingServer(_config.indexId);\n                    // Wait for delay calculation (10 seconds)\n                    ConnectVPNLabel = ResUI.HomeConnecting;\n                    short count = 1;\n                    while (!IsDelayCalculationFinished)\n                    {\n                        // We don't want to stuck in a infinite loop\n                        if (count == 25)\n                            break;\n\n                        await Task.Delay(400).ConfigureAwait(false);\n                        count += 1;\n                    }\n                    ConnectProgress = false;\n                    DelayProgress = false;\n                    //DialogHost.CloseDialogCommand.Execute(\"\",null);\n                    \n                    // Check delay\n                    if (SelectedProfileDelay > 0 && SelectedProfileDelay != -1)\n                    {\n                        // The server works\n                        \n                        //TODO: @hiddify1; change the connectVPN color to whatever should be\n                        ConnectVPNLabelColor = \"#7CFC0000\";\n                        ConnectVPNLabel = ResUI.HomeConnected;\n                        ConnectColor = \"#33d91a\";\n                        IsConnected = true;\n                        SetSysProxy();\n                        return;\n                    }\n                    else\n                    {\n                        // The server doesn't work\n                        ConnectColor = \"#d6003b\";\n                        ConnectVPNLabel = ResUI.HomeNotConnected;\n                        IsConnected = false;\n                        return;\n                    }\n\n                }\n\n            }\n\n            // It's connected, should be disconnected\n            {\n                //TODO: @hiddify1; change the connectVPN color to whatever should be\n                //ConnectColor = \"#FFFF0000\";\n                ConnectColor = \"#d6003b\";\n                ConnectVPNLabel = ResUI.HomeDisconnected;\n                ConnectVPNLabelColor = \"#FFFF0000\";\n                IsConnected = false;\n                UnsetSysProxy();\n            }\n        }\n        public void HomeGotoProfile(string subId)\n        {\n            SubItem sub = LazyConfig.Instance.GetSubItem(subId);\n            var ret = (new SubEditWindow(sub)).ShowDialog();\n            if (ret == true)\n            {\n                InitSubscriptionView();\n            }\n        }\n        private void HomeDeleteSub()\n        {\n            if (SelectedSub != null)\n            {\n                if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)\n                    return;\n                else\n                {\n                    ConfigHandler.DeleteSubItem(ref _config, SelectedSub.id);\n                    InitSubscriptionView();\n                }\n            }\n        }\n        public void HomeSelectedRouteChanged()\n        {\n            Console.WriteLine(HomeSelectedRoutingItem);\n            \n        }\n        public async Task HomeSelectedProxyChanged()\n        {\n            ProfileExpanded = false;\n            if (HomeSelectedProxyMode== ProxyModeEnum.Manual)\n            { \n                ToggleV2rayPanel();\n                return;\n            }\n            else if (V2RayNPanelVisible)\n            {\n                ToggleV2rayPanel();\n            }\n            if (IsConnected)\n            {\n                await HomeConnect(true).ConfigureAwait(false);\n            }\n        }\n        #endregion\n\n        private void ToggleV2rayPanel()\n        {\n            V2RayNPanelVisible = !V2RayNPanelVisible;\n\n            MaxWindowWidth = V2RayNPanelVisible ? 2100 : 420;\n            WindowWidth = V2RayNPanelVisible ? 1200 : 420;\n            ColorModeDark = !ColorModeDark;\n            ColorModeDark = !ColorModeDark;\n        }\n\n        private ProfileItem? GetSelectedServer(string subId,ProxyModeEnum proxyMode)\n        {\n            if (subId.IsNullOrEmpty() || proxyMode==null)\n                return null;\n\n\n            // Get selected sub items proxies/servers\n            var subServers = LazyConfig.Instance.ProfileItems(SelectedSub.id);\n            if (subServers.Count < 1)\n            {\n                return null;\n            }\n\n            if (proxyMode == ProxyModeEnum.Manual)\n                return null;\n\n            ProfileItem server = null;\n\n            if (proxyMode == ProxyModeEnum.Smart)\n            {\n                server = subServers.FirstOrDefault(s => s.remarks == \"Lowest Ping\");\n            }\n            else if (proxyMode == ProxyModeEnum.Loadbalance)\n            {\n                server = subServers.FirstOrDefault(s => s.remarks == \"Load Balance\");\n            }\n            else\n            {\n                return null;\n            }\n            return server;\n        }\n\n        private async Task HomeRealPingServer(string serverIndexId)\n        {\n            SelectedProfileDelay = 0;\n            IsDelayCalculationFinished = false;\n            //DelayProgress = true;\n            ProfileItem server = LazyConfig.Instance.GetProfileItem(serverIndexId);\n            if (server != null)\n            {\n                //ClearTestResult();\n                await Task.Run(() =>\n                {\n                    new SpeedtestHandler(_config, _coreHandler, new List<ProfileItem>() { server }, ESpeedActionType.Realping, UpdateHomeRealPingServer);\n                });\n                \n            }\n        }\n        private void UpdateHomeRealPingServer(string indexId, string delay, string speed)\n        {\n            bool isNumberic = int.TryParse(delay, out int res);\n            if (isNumberic)\n            {\n                SelectedProfileDelay = Convert.ToInt32(res);\n                IsDelayCalculationFinished = true;\n                //DelayProgress = false;\n            }\n            \n        }\n       \n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs",
    "content": "﻿using ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.ViewModels\n{\n    public class OptionSettingViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n\n        #region Core\n\n        [Reactive] public int localPort { get; set; }\n        [Reactive] public bool udpEnabled { get; set; }\n        [Reactive] public bool sniffingEnabled { get; set; }\n        [Reactive] public bool routeOnly { get; set; }\n        [Reactive] public bool allowLANConn { get; set; }\n        [Reactive] public bool newPort4LAN { get; set; }\n        [Reactive] public string user { get; set; }\n        [Reactive] public string pass { get; set; }\n        [Reactive] public bool muxEnabled { get; set; }\n        [Reactive] public bool logEnabled { get; set; }\n        [Reactive] public string loglevel { get; set; }\n        [Reactive] public bool defAllowInsecure { get; set; }\n        [Reactive] public string defFingerprint { get; set; }\n        [Reactive] public string defUserAgent { get; set; }\n\n        #endregion Core\n\n        #region Core KCP\n\n        //[Reactive] public int Kcpmtu { get; set; }\n        //[Reactive] public int Kcptti { get; set; }\n        //[Reactive] public int KcpuplinkCapacity { get; set; }\n        //[Reactive] public int KcpdownlinkCapacity { get; set; }\n        //[Reactive] public int KcpreadBufferSize { get; set; }\n        //[Reactive] public int KcpwriteBufferSize { get; set; }\n        //[Reactive] public bool Kcpcongestion { get; set; }\n\n        #endregion Core KCP\n\n        #region UI\n\n        [Reactive] public bool AutoRun { get; set; }\n        [Reactive] public bool EnableStatistics { get; set; }\n        [Reactive] public int StatisticsFreshRate { get; set; }\n        [Reactive] public bool KeepOlderDedupl { get; set; }\n        [Reactive] public bool IgnoreGeoUpdateCore { get; set; }\n        [Reactive] public bool EnableAutoAdjustMainLvColWidth { get; set; }\n        [Reactive] public bool EnableSecurityProtocolTls13 { get; set; } = true;\n        [Reactive] public bool AutoHideStartup { get; set; }\n        [Reactive] public bool EnableCheckPreReleaseUpdate { get; set; }\n        [Reactive] public bool EnableDragDropSort { get; set; }\n        [Reactive] public bool DoubleClick2Activate { get; set; }\n        [Reactive] public int autoUpdateInterval { get; set; }\n        [Reactive] public int trayMenuServersLimit { get; set; }\n        [Reactive] public string currentFontFamily { get; set; }\n        [Reactive] public int SpeedTestTimeout { get; set; }\n        [Reactive] public string SpeedTestUrl { get; set; }\n        [Reactive] public bool EnableHWA { get; set; }\n        [Reactive] public string SubConvertUrl { get; set; }\n\n        #endregion UI\n\n        #region System proxy\n\n        [Reactive] public string systemProxyAdvancedProtocol { get; set; }\n        [Reactive] public string systemProxyExceptions { get; set; }\n\n        #endregion System proxy\n\n        #region Tun mode\n\n        [Reactive] public bool TunShowWindow { get; set; }\n        [Reactive] public bool TunEnabledLog { get; set; }\n        [Reactive] public bool TunStrictRoute { get; set; }\n        [Reactive] public string TunStack { get; set; }\n        [Reactive] public int TunMtu { get; set; }\n        [Reactive] public string TunCustomTemplate { get; set; }\n        [Reactive] public bool TunBypassMode { get; set; }\n        [Reactive] public bool TunBypassMode2 { get; set; }\n        [Reactive] public string TunDirectIP { get; set; }\n        [Reactive] public string TunDirectProcess { get; set; }\n        [Reactive] public string TunDirectDNS { get; set; }\n        [Reactive] public string TunProxyIP { get; set; }\n        [Reactive] public string TunProxyProcess { get; set; }\n        [Reactive] public string TunProxyDNS { get; set; }\n\n        #endregion Tun mode\n\n        #region CoreType\n\n        [Reactive] public string CoreType1 { get; set; }\n        [Reactive] public string CoreType2 { get; set; }\n        [Reactive] public string CoreType3 { get; set; }\n        [Reactive] public string CoreType4 { get; set; }\n        [Reactive] public string CoreType5 { get; set; }\n        [Reactive] public string CoreType6 { get; set; }\n\n        #endregion CoreType\n\n        public ReactiveCommand<Unit, Unit> SaveCmd { get; }\n\n        public OptionSettingViewModel(Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _view = view;\n\n            #region Core\n\n            var inbound = _config.inbound[0];\n            localPort = inbound.localPort;\n            udpEnabled = inbound.udpEnabled;\n            sniffingEnabled = inbound.sniffingEnabled;\n            routeOnly = inbound.routeOnly;\n            allowLANConn = inbound.allowLANConn;\n            newPort4LAN = inbound.newPort4LAN;\n            user = inbound.user;\n            pass = inbound.pass;\n            muxEnabled = _config.coreBasicItem.muxEnabled;\n            logEnabled = _config.coreBasicItem.logEnabled;\n            loglevel = _config.coreBasicItem.loglevel;\n            defAllowInsecure = _config.coreBasicItem.defAllowInsecure;\n            defFingerprint = _config.coreBasicItem.defFingerprint;\n            defUserAgent = _config.coreBasicItem.defUserAgent;\n\n            #endregion Core\n\n            #region Core KCP\n\n            //Kcpmtu = _config.kcpItem.mtu;\n            //Kcptti = _config.kcpItem.tti;\n            //KcpuplinkCapacity = _config.kcpItem.uplinkCapacity;\n            //KcpdownlinkCapacity = _config.kcpItem.downlinkCapacity;\n            //KcpreadBufferSize = _config.kcpItem.readBufferSize;\n            //KcpwriteBufferSize = _config.kcpItem.writeBufferSize;\n            //Kcpcongestion = _config.kcpItem.congestion;\n\n            #endregion Core KCP\n\n            #region UI\n\n            AutoRun = _config.guiItem.autoRun;\n            EnableStatistics = _config.guiItem.enableStatistics;\n            StatisticsFreshRate = _config.guiItem.statisticsFreshRate;\n            KeepOlderDedupl = _config.guiItem.keepOlderDedupl;\n            IgnoreGeoUpdateCore = _config.guiItem.ignoreGeoUpdateCore;\n            EnableAutoAdjustMainLvColWidth = _config.uiItem.enableAutoAdjustMainLvColWidth;\n            EnableSecurityProtocolTls13 = _config.guiItem.enableSecurityProtocolTls13;\n            AutoHideStartup = _config.uiItem.autoHideStartup;\n            EnableCheckPreReleaseUpdate = _config.guiItem.checkPreReleaseUpdate;\n            EnableDragDropSort = _config.uiItem.enableDragDropSort;\n            DoubleClick2Activate = _config.uiItem.doubleClick2Activate;\n            autoUpdateInterval = _config.guiItem.autoUpdateInterval;\n            trayMenuServersLimit = _config.guiItem.trayMenuServersLimit;\n            currentFontFamily = _config.uiItem.currentFontFamily;\n            SpeedTestTimeout = _config.speedTestItem.speedTestTimeout;\n            SpeedTestUrl = _config.speedTestItem.speedTestUrl;\n            EnableHWA = _config.guiItem.enableHWA;\n            SubConvertUrl = _config.constItem.subConvertUrl;\n\n            #endregion UI\n\n            #region System proxy\n\n            systemProxyAdvancedProtocol = _config.systemProxyAdvancedProtocol;\n            systemProxyExceptions = _config.systemProxyExceptions;\n\n            #endregion System proxy\n\n            #region Tun mode\n\n            TunShowWindow = _config.tunModeItem.showWindow;\n            TunEnabledLog = _config.tunModeItem.enabledLog;\n            TunStrictRoute = _config.tunModeItem.strictRoute;\n            TunStack = _config.tunModeItem.stack;\n            TunMtu = _config.tunModeItem.mtu;\n            TunCustomTemplate = _config.tunModeItem.customTemplate;\n            TunBypassMode = _config.tunModeItem.bypassMode;\n            TunDirectIP = Utils.List2String(_config.tunModeItem.directIP, true);\n            TunDirectProcess = Utils.List2String(_config.tunModeItem.directProcess, true);\n            TunDirectDNS = _config.tunModeItem.directDNS;\n            TunProxyIP = Utils.List2String(_config.tunModeItem.proxyIP, true);\n            TunProxyProcess = Utils.List2String(_config.tunModeItem.proxyProcess, true);\n            TunProxyDNS = _config.tunModeItem.proxyDNS;\n            this.WhenAnyValue(\n              x => x.TunBypassMode)\n              .Subscribe(c => TunBypassMode2 = !TunBypassMode);\n\n            #endregion Tun mode\n\n            InitCoreType();\n\n            SaveCmd = ReactiveCommand.Create(() =>\n            {\n                SaveSetting();\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        private void InitCoreType()\n        {\n            if (_config.coreTypeItem == null)\n            {\n                _config.coreTypeItem = new List<CoreTypeItem>();\n            }\n\n            foreach (EConfigType it in Enum.GetValues(typeof(EConfigType)))\n            {\n                if (_config.coreTypeItem.FindIndex(t => t.configType == it) >= 0)\n                {\n                    continue;\n                }\n\n                _config.coreTypeItem.Add(new CoreTypeItem()\n                {\n                    configType = it,\n                    coreType = ECoreType.Xray\n                });\n            }\n            _config.coreTypeItem.ForEach(it =>\n            {\n                var type = it.coreType.ToString();\n                switch ((int)it.configType)\n                {\n                    case 1:\n                        CoreType1 = type;\n                        break;\n\n                    case 2:\n                        CoreType2 = type;\n                        break;\n\n                    case 3:\n                        CoreType3 = type;\n                        break;\n\n                    case 4:\n                        CoreType4 = type;\n                        break;\n\n                    case 5:\n                        CoreType5 = type;\n                        break;\n\n                    case 6:\n                        CoreType6 = type;\n                        break;\n                }\n            });\n        }\n\n        private void SaveSetting()\n        {\n            if (Utils.IsNullOrEmpty(localPort.ToString()) || !Utils.IsNumberic(localPort.ToString())\n               || localPort <= 0 || localPort >= Global.MaxPort)\n            {\n                UI.Show(ResUI.FillLocalListeningPort);\n                return;\n            }\n\n            //if (Utils.IsNullOrEmpty(Kcpmtu.ToString()) || !Utils.IsNumberic(Kcpmtu.ToString())\n            //       || Utils.IsNullOrEmpty(Kcptti.ToString()) || !Utils.IsNumberic(Kcptti.ToString())\n            //       || Utils.IsNullOrEmpty(KcpuplinkCapacity.ToString()) || !Utils.IsNumberic(KcpuplinkCapacity.ToString())\n            //       || Utils.IsNullOrEmpty(KcpdownlinkCapacity.ToString()) || !Utils.IsNumberic(KcpdownlinkCapacity.ToString())\n            //       || Utils.IsNullOrEmpty(KcpreadBufferSize.ToString()) || !Utils.IsNumberic(KcpreadBufferSize.ToString())\n            //       || Utils.IsNullOrEmpty(KcpwriteBufferSize.ToString()) || !Utils.IsNumberic(KcpwriteBufferSize.ToString()))\n            //{\n            //    UI.Show(ResUI.FillKcpParameters);\n            //    return;\n            //}\n\n            //Core\n            _config.inbound[0].localPort = localPort;\n            _config.inbound[0].udpEnabled = udpEnabled;\n            _config.inbound[0].sniffingEnabled = sniffingEnabled;\n            _config.inbound[0].routeOnly = routeOnly;\n            _config.inbound[0].allowLANConn = allowLANConn;\n            _config.inbound[0].newPort4LAN = newPort4LAN;\n            _config.inbound[0].user = user;\n            _config.inbound[0].pass = pass;\n            if (_config.inbound.Count > 1)\n            {\n                _config.inbound.RemoveAt(1);\n            }\n            _config.coreBasicItem.logEnabled = logEnabled;\n            _config.coreBasicItem.loglevel = loglevel;\n            _config.coreBasicItem.muxEnabled = muxEnabled;\n            _config.coreBasicItem.defAllowInsecure = defAllowInsecure;\n            _config.coreBasicItem.defFingerprint = defFingerprint;\n            _config.coreBasicItem.defUserAgent = defUserAgent;\n\n            //Kcp\n            //_config.kcpItem.mtu = Kcpmtu;\n            //_config.kcpItem.tti = Kcptti;\n            //_config.kcpItem.uplinkCapacity = KcpuplinkCapacity;\n            //_config.kcpItem.downlinkCapacity = KcpdownlinkCapacity;\n            //_config.kcpItem.readBufferSize = KcpreadBufferSize;\n            //_config.kcpItem.writeBufferSize = KcpwriteBufferSize;\n            //_config.kcpItem.congestion = Kcpcongestion;\n\n            //UI\n            Utils.SetAutoRun(AutoRun);\n            _config.guiItem.autoRun = AutoRun;\n            _config.guiItem.enableStatistics = EnableStatistics;\n            _config.guiItem.statisticsFreshRate = StatisticsFreshRate;\n            if (_config.guiItem.statisticsFreshRate > 100 || _config.guiItem.statisticsFreshRate < 1)\n            {\n                _config.guiItem.statisticsFreshRate = 1;\n            }\n            _config.guiItem.keepOlderDedupl = KeepOlderDedupl;\n            _config.guiItem.ignoreGeoUpdateCore = IgnoreGeoUpdateCore;\n            _config.uiItem.enableAutoAdjustMainLvColWidth = EnableAutoAdjustMainLvColWidth;\n            _config.guiItem.enableSecurityProtocolTls13 = EnableSecurityProtocolTls13;\n            _config.uiItem.autoHideStartup = AutoHideStartup;\n            _config.guiItem.autoUpdateInterval = autoUpdateInterval;\n            _config.guiItem.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate;\n            _config.uiItem.enableDragDropSort = EnableDragDropSort;\n            _config.uiItem.doubleClick2Activate = DoubleClick2Activate;\n            _config.guiItem.trayMenuServersLimit = trayMenuServersLimit;\n            _config.uiItem.currentFontFamily = currentFontFamily;\n            _config.speedTestItem.speedTestTimeout = SpeedTestTimeout;\n            _config.speedTestItem.speedTestUrl = SpeedTestUrl;\n            _config.guiItem.enableHWA = EnableHWA;\n            _config.constItem.subConvertUrl = SubConvertUrl;\n\n            //systemProxy\n            _config.systemProxyExceptions = systemProxyExceptions;\n            _config.systemProxyAdvancedProtocol = systemProxyAdvancedProtocol;\n\n            //tun mode\n            _config.tunModeItem.showWindow = TunShowWindow;\n            _config.tunModeItem.enabledLog = TunEnabledLog;\n            _config.tunModeItem.strictRoute = TunStrictRoute;\n            _config.tunModeItem.stack = TunStack;\n            _config.tunModeItem.mtu = TunMtu;\n            _config.tunModeItem.customTemplate = TunCustomTemplate;\n            _config.tunModeItem.bypassMode = TunBypassMode;\n            _config.tunModeItem.directIP = Utils.String2List(Utils.Convert2Comma(TunDirectIP));\n            _config.tunModeItem.directProcess = Utils.String2List(Utils.Convert2Comma(TunDirectProcess));\n            _config.tunModeItem.directDNS = Utils.ToJson(Utils.ParseJson(TunDirectDNS));\n            _config.tunModeItem.proxyIP = Utils.String2List(Utils.Convert2Comma(TunProxyIP));\n            _config.tunModeItem.proxyProcess = Utils.String2List(Utils.Convert2Comma(TunProxyProcess));\n            _config.tunModeItem.proxyDNS = Utils.ToJson(Utils.ParseJson(TunProxyDNS));\n\n            //coreType\n            SaveCoreType();\n\n            if (ConfigHandler.SaveConfig(ref _config) == 0)\n            {\n                _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n                _view.DialogResult = true;\n            }\n            else\n            {\n                UI.ShowWarning(ResUI.OperationFailed);\n            }\n        }\n\n        private int SaveCoreType()\n        {\n            for (int k = 1; k <= _config.coreTypeItem.Count; k++)\n            {\n                var item = _config.coreTypeItem[k - 1];\n                var type = string.Empty;\n                switch ((int)item.configType)\n                {\n                    case 1:\n                        type = CoreType1;\n                        break;\n\n                    case 2:\n                        type = CoreType2;\n                        break;\n\n                    case 3:\n                        type = CoreType3;\n                        break;\n\n                    case 4:\n                        type = CoreType4;\n                        break;\n\n                    case 5:\n                        type = CoreType5;\n                        break;\n\n                    case 6:\n                        type = CoreType6;\n                        break;\n                    case 101:\n                    case 102:\n                    case 103:\n                        type = CoreType2;\n                        break;\n                }\n                item.coreType = (ECoreType)Enum.Parse(typeof(ECoreType), type);\n            }\n            return 0;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs",
    "content": "﻿using ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.ViewModels\n{\n    public class RoutingRuleDetailsViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n\n        public IList<string> ProtocolItems { get; set; }\n        public IList<string> InboundTagItems { get; set; }\n\n        [Reactive]\n        public RulesItem SelectedSource { get; set; }\n\n        [Reactive]\n        public string Domain { get; set; }\n\n        [Reactive]\n        public string IP { get; set; }\n\n        [Reactive]\n        public bool AutoSort { get; set; }\n\n        public ReactiveCommand<Unit, Unit> SaveCmd { get; }\n\n        public RoutingRuleDetailsViewModel(RulesItem rulesItem, Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _view = view;\n\n            if (rulesItem.id.IsNullOrEmpty())\n            {\n                rulesItem.id = Utils.GetGUID(false);\n                rulesItem.outboundTag = Global.agentTag;\n                rulesItem.enabled = true;\n                SelectedSource = rulesItem;\n            }\n            else\n            {\n                SelectedSource = rulesItem;\n            }\n\n            Domain = Utils.List2String(SelectedSource.domain, true);\n            IP = Utils.List2String(SelectedSource.ip, true);\n\n            SaveCmd = ReactiveCommand.Create(() =>\n            {\n                SaveRules();\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        private void SaveRules()\n        {\n            Domain = Utils.Convert2Comma(Domain);\n            IP = Utils.Convert2Comma(IP);\n\n            if (AutoSort)\n            {\n                SelectedSource.domain = Utils.String2ListSorted(Domain);\n                SelectedSource.ip = Utils.String2ListSorted(IP);\n            }\n            else\n            {\n                SelectedSource.domain = Utils.String2List(Domain);\n                SelectedSource.ip = Utils.String2List(IP);\n            }\n            SelectedSource.protocol = ProtocolItems?.ToList();\n            SelectedSource.inboundTag = InboundTagItems?.ToList();\n\n            bool hasRule =\n              SelectedSource.domain != null\n              && SelectedSource.domain.Count > 0\n              || SelectedSource.ip != null\n              && SelectedSource.ip.Count > 0\n              || SelectedSource.protocol != null\n              && SelectedSource.protocol.Count > 0\n              || !Utils.IsNullOrEmpty(SelectedSource.port);\n\n            if (!hasRule)\n            {\n                UI.ShowWarning(string.Format(ResUI.RoutingRuleDetailRequiredTips, \"Port/Protocol/Domain/IP\"));\n                return;\n            }\n            //_noticeHandler?.Enqueue(ResUI.OperationSuccess);\n            _view.DialogResult = true;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs",
    "content": "﻿using DynamicData.Binding;\nusing Microsoft.Win32;\nusing ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\nusing v2rayN.Views;\nusing Application = System.Windows.Application;\n\nnamespace v2rayN.ViewModels\n{\n    public class RoutingRuleSettingViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n        private List<RulesItem> _rules;\n\n        [Reactive]\n        public RoutingItem SelectedRouting { get; set; }\n\n        private IObservableCollection<RulesItemModel> _rulesItems = new ObservableCollectionExtended<RulesItemModel>();\n        public IObservableCollection<RulesItemModel> RulesItems => _rulesItems;\n\n        [Reactive]\n        public RulesItemModel SelectedSource { get; set; }\n\n        public IList<RulesItemModel> SelectedSources { get; set; }\n\n        public ReactiveCommand<Unit, Unit> RuleAddCmd { get; }\n        public ReactiveCommand<Unit, Unit> ImportRulesFromFileCmd { get; }\n        public ReactiveCommand<Unit, Unit> ImportRulesFromClipboardCmd { get; }\n        public ReactiveCommand<Unit, Unit> ImportRulesFromUrlCmd { get; }\n        public ReactiveCommand<Unit, Unit> RuleRemoveCmd { get; }\n        public ReactiveCommand<Unit, Unit> RuleExportSelectedCmd { get; }\n        public ReactiveCommand<Unit, Unit> MoveTopCmd { get; }\n        public ReactiveCommand<Unit, Unit> MoveUpCmd { get; }\n        public ReactiveCommand<Unit, Unit> MoveDownCmd { get; }\n        public ReactiveCommand<Unit, Unit> MoveBottomCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> SaveCmd { get; }\n\n        public RoutingRuleSettingViewModel(RoutingItem routingItem, Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _view = view;\n            SelectedSource = new();\n\n            if (routingItem.id.IsNullOrEmpty())\n            {\n                SelectedRouting = routingItem;\n                _rules = new();\n            }\n            else\n            {\n                SelectedRouting = routingItem;\n                _rules = Utils.FromJson<List<RulesItem>>(SelectedRouting.ruleSet);\n            }\n\n            RefreshRulesItems();\n\n            var canEditRemove = this.WhenAnyValue(\n               x => x.SelectedSource,\n               selectedSource => selectedSource != null && !selectedSource.outboundTag.IsNullOrEmpty());\n\n            RuleAddCmd = ReactiveCommand.Create(() =>\n            {\n                RuleEdit(true);\n            });\n            ImportRulesFromFileCmd = ReactiveCommand.Create(() =>\n            {\n                ImportRulesFromFile();\n            });\n            ImportRulesFromClipboardCmd = ReactiveCommand.Create(() =>\n            {\n                ImportRulesFromClipboard();\n            });\n            ImportRulesFromUrlCmd = ReactiveCommand.Create(() =>\n            {\n                ImportRulesFromUrl();\n            });\n\n            RuleRemoveCmd = ReactiveCommand.Create(() =>\n            {\n                RuleRemove();\n            }, canEditRemove);\n            RuleExportSelectedCmd = ReactiveCommand.Create(() =>\n            {\n                RuleExportSelected();\n            }, canEditRemove);\n\n            MoveTopCmd = ReactiveCommand.Create(() =>\n            {\n                MoveRule(EMove.Top);\n            }, canEditRemove);\n            MoveUpCmd = ReactiveCommand.Create(() =>\n            {\n                MoveRule(EMove.Up);\n            }, canEditRemove);\n            MoveDownCmd = ReactiveCommand.Create(() =>\n            {\n                MoveRule(EMove.Down);\n            }, canEditRemove);\n            MoveBottomCmd = ReactiveCommand.Create(() =>\n            {\n                MoveRule(EMove.Bottom);\n            }, canEditRemove);\n\n            SaveCmd = ReactiveCommand.Create(() =>\n            {\n                SaveRouting();\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        public void RefreshRulesItems()\n        {\n            _rulesItems.Clear();\n\n            foreach (var item in _rules)\n            {\n                var it = new RulesItemModel()\n                {\n                    id = item.id,\n                    outboundTag = item.outboundTag,\n                    port = item.port,\n                    protocols = Utils.List2String(item.protocol),\n                    inboundTags = Utils.List2String(item.inboundTag),\n                    domains = Utils.List2String(item.domain),\n                    ips = Utils.List2String(item.ip),\n                    enabled = item.enabled,\n                };\n                _rulesItems.Add(it);\n            }\n        }\n\n        public void RuleEdit(bool blNew)\n        {\n            RulesItem item;\n            if (blNew)\n            {\n                item = new();\n            }\n            else\n            {\n                item = _rules.FirstOrDefault(t => t.id == SelectedSource?.id);\n                if (item is null)\n                {\n                    return;\n                }\n            }\n            var ret = (new RoutingRuleDetailsWindow(item)).ShowDialog();\n            if (ret == true)\n            {\n                if (blNew)\n                {\n                    _rules.Add(item);\n                }\n                RefreshRulesItems();\n            }\n        }\n\n        public void RuleRemove()\n        {\n            if (SelectedSource is null || SelectedSource.outboundTag.IsNullOrEmpty())\n            {\n                UI.Show(ResUI.PleaseSelectRules);\n                return;\n            }\n            if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)\n            {\n                return;\n            }\n            foreach (var it in SelectedSources)\n            {\n                var item = _rules.FirstOrDefault(t => t.id == it?.id);\n                if (item != null)\n                {\n                    _rules.Remove(item);\n                }\n            }\n\n            RefreshRulesItems();\n        }\n\n        public void RuleExportSelected()\n        {\n            if (SelectedSource is null || SelectedSource.outboundTag.IsNullOrEmpty())\n            {\n                UI.Show(ResUI.PleaseSelectRules);\n                return;\n            }\n\n            var lst = new List<RulesItem>();\n            foreach (var it in SelectedSources)\n            {\n                var item = _rules.FirstOrDefault(t => t.id == it?.id);\n                if (item != null)\n                {\n                    lst.Add(item);\n                }\n            }\n            if (lst.Count > 0)\n            {\n                Utils.SetClipboardData(Utils.ToJson(lst));\n                //UI.Show(ResUI.OperationSuccess\"));\n            }\n        }\n\n        public void MoveRule(EMove eMove)\n        {\n            if (SelectedSource is null || SelectedSource.outboundTag.IsNullOrEmpty())\n            {\n                UI.Show(ResUI.PleaseSelectRules);\n                return;\n            }\n\n            var item = _rules.FirstOrDefault(t => t.id == SelectedSource?.id);\n            if (item == null)\n            {\n                return;\n            }\n            var index = _rules.IndexOf(item);\n            if (ConfigHandler.MoveRoutingRule(_rules, index, eMove) == 0)\n            {\n                RefreshRulesItems();\n            }\n        }\n\n        private void SaveRouting()\n        {\n            string remarks = SelectedRouting.remarks;\n            if (Utils.IsNullOrEmpty(remarks))\n            {\n                UI.Show(ResUI.PleaseFillRemarks);\n                return;\n            }\n            var item = SelectedRouting;\n            foreach (var it in _rules)\n            {\n                it.id = Utils.GetGUID(false);\n            }\n            item.ruleNum = _rules.Count;\n            item.ruleSet = Utils.ToJson(_rules, false);\n\n            if (ConfigHandler.SaveRoutingItem(ref _config, item) == 0)\n            {\n                _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n                _view.DialogResult = true;\n            }\n            else\n            {\n                UI.ShowWarning(ResUI.OperationFailed);\n            }\n        }\n\n        #region Import rules\n\n        private void ImportRulesFromFile()\n        {\n            OpenFileDialog fileDialog = new OpenFileDialog\n            {\n                Multiselect = false,\n                Filter = \"Rules|*.json|All|*.*\"\n            };\n            if (fileDialog.ShowDialog() != true)\n            {\n                return;\n            }\n            string fileName = fileDialog.FileName;\n            if (Utils.IsNullOrEmpty(fileName))\n            {\n                return;\n            }\n            string result = Utils.LoadResource(fileName);\n            if (Utils.IsNullOrEmpty(result))\n            {\n                return;\n            }\n\n            if (AddBatchRoutingRules(SelectedRouting, result) == 0)\n            {\n                RefreshRulesItems();\n                UI.Show(ResUI.OperationSuccess);\n            }\n        }\n\n        private void ImportRulesFromClipboard()\n        {\n            string clipboardData = Utils.GetClipboardData();\n            if (AddBatchRoutingRules(SelectedRouting, clipboardData) == 0)\n            {\n                RefreshRulesItems();\n                UI.Show(ResUI.OperationSuccess);\n            }\n        }\n\n        private async Task ImportRulesFromUrl()\n        {\n            var url = SelectedRouting.url;\n            if (Utils.IsNullOrEmpty(url))\n            {\n                UI.Show(ResUI.MsgNeedUrl);\n                return;\n            }\n\n            DownloadHandle downloadHandle = new DownloadHandle();\n            string result = await downloadHandle.TryDownloadString(url, true, \"\");\n            if (AddBatchRoutingRules(SelectedRouting, result) == 0)\n            {\n                Application.Current.Dispatcher.Invoke((Action)(() =>\n                {\n                    RefreshRulesItems();\n                }));\n                UI.Show(ResUI.OperationSuccess);\n            }\n        }\n\n        private int AddBatchRoutingRules(RoutingItem routingItem, string clipboardData)\n        {\n            bool blReplace = false;\n            if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No)\n            {\n                blReplace = true;\n            }\n            if (Utils.IsNullOrEmpty(clipboardData))\n            {\n                return -1;\n            }\n            var lstRules = Utils.FromJson<List<RulesItem>>(clipboardData);\n            if (lstRules == null)\n            {\n                return -1;\n            }\n            foreach (var rule in lstRules)\n            {\n                rule.id = Utils.GetGUID(false);\n            }\n\n            if (blReplace)\n            {\n                _rules = lstRules;\n            }\n            else\n            {\n                _rules.AddRange(lstRules);\n            }\n            return 0;\n        }\n\n        #endregion Import rules\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/RoutingSettingViewModel.cs",
    "content": "﻿using DynamicData.Binding;\nusing ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\nusing v2rayN.Views;\n\nnamespace v2rayN.ViewModels\n{\n    public class RoutingSettingViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n        private RoutingItem _lockedItem;\n        private List<RulesItem> _lockedRules;\n\n        #region Reactive\n\n        private IObservableCollection<RoutingItemModel> _routingItems = new ObservableCollectionExtended<RoutingItemModel>();\n        public IObservableCollection<RoutingItemModel> RoutingItems => _routingItems;\n\n        [Reactive]\n        public RoutingItemModel SelectedSource { get; set; }\n\n        public IList<RoutingItemModel> SelectedSources { get; set; }\n\n        [Reactive]\n        public bool enableRoutingAdvanced { get; set; }\n\n        [Reactive]\n        public bool enableRoutingBasic { get; set; }\n\n        [Reactive]\n        public string domainStrategy { get; set; }\n\n        [Reactive]\n        public string domainMatcher { get; set; }\n\n        [Reactive]\n        public string domainStrategy4Singbox { get; set; }\n\n        [Reactive]\n        public string ProxyDomain { get; set; }\n\n        [Reactive]\n        public string ProxyIP { get; set; }\n\n        [Reactive]\n        public string DirectDomain { get; set; }\n\n        [Reactive]\n        public string DirectIP { get; set; }\n\n        [Reactive]\n        public string BlockDomain { get; set; }\n\n        [Reactive]\n        public string BlockIP { get; set; }\n\n        public ReactiveCommand<Unit, Unit> RoutingBasicImportRulesCmd { get; }\n        public ReactiveCommand<Unit, Unit> RoutingAdvancedAddCmd { get; }\n        public ReactiveCommand<Unit, Unit> RoutingAdvancedRemoveCmd { get; }\n        public ReactiveCommand<Unit, Unit> RoutingAdvancedSetDefaultCmd { get; }\n        public ReactiveCommand<Unit, Unit> RoutingAdvancedImportRulesCmd { get; }\n\n        public ReactiveCommand<Unit, Unit> SaveCmd { get; }\n        public bool IsModified { get; set; }\n\n        #endregion Reactive\n\n        public RoutingSettingViewModel(Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _view = view;\n            SelectedSource = new();\n\n            ConfigHandler.InitBuiltinRouting(ref _config);\n\n            enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced;\n            domainStrategy = _config.routingBasicItem.domainStrategy;\n            domainMatcher = _config.routingBasicItem.domainMatcher;\n            domainStrategy4Singbox = _config.routingBasicItem.domainStrategy4Singbox;\n\n            RefreshRoutingItems();\n\n            BindingLockedData();\n\n            var canEditRemove = this.WhenAnyValue(\n               x => x.SelectedSource,\n               selectedSource => selectedSource != null && !selectedSource.remarks.IsNullOrEmpty());\n\n            this.WhenAnyValue(\n                x => x.enableRoutingAdvanced)\n                .Subscribe(c => enableRoutingBasic = !enableRoutingAdvanced);\n\n            RoutingBasicImportRulesCmd = ReactiveCommand.Create(() =>\n            {\n                RoutingBasicImportRules();\n            });\n\n            RoutingAdvancedAddCmd = ReactiveCommand.Create(() =>\n            {\n                RoutingAdvancedEdit(true);\n            });\n            RoutingAdvancedRemoveCmd = ReactiveCommand.Create(() =>\n            {\n                RoutingAdvancedRemove();\n            }, canEditRemove);\n            RoutingAdvancedSetDefaultCmd = ReactiveCommand.Create(() =>\n            {\n                RoutingAdvancedSetDefault();\n            }, canEditRemove);\n            RoutingAdvancedImportRulesCmd = ReactiveCommand.Create(() =>\n            {\n                RoutingAdvancedImportRules();\n            });\n\n            SaveCmd = ReactiveCommand.Create(() =>\n            {\n                SaveRouting();\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        #region locked\n\n        private void BindingLockedData()\n        {\n            _lockedItem = ConfigHandler.GetLockedRoutingItem(ref _config);\n            if (_lockedItem != null)\n            {\n                _lockedRules = Utils.FromJson<List<RulesItem>>(_lockedItem.ruleSet);\n                ProxyDomain = Utils.List2String(_lockedRules[0].domain, true);\n                ProxyIP = Utils.List2String(_lockedRules[0].ip, true);\n\n                DirectDomain = Utils.List2String(_lockedRules[1].domain, true);\n                DirectIP = Utils.List2String(_lockedRules[1].ip, true);\n\n                BlockDomain = Utils.List2String(_lockedRules[2].domain, true);\n                BlockIP = Utils.List2String(_lockedRules[2].ip, true);\n            }\n        }\n\n        private void EndBindingLockedData()\n        {\n            if (_lockedItem != null)\n            {\n                _lockedRules[0].domain = Utils.String2List(Utils.Convert2Comma(ProxyDomain.TrimEx()));\n                _lockedRules[0].ip = Utils.String2List(Utils.Convert2Comma(ProxyIP.TrimEx()));\n\n                _lockedRules[1].domain = Utils.String2List(Utils.Convert2Comma(DirectDomain.TrimEx()));\n                _lockedRules[1].ip = Utils.String2List(Utils.Convert2Comma(DirectIP.TrimEx()));\n\n                _lockedRules[2].domain = Utils.String2List(Utils.Convert2Comma(BlockDomain.TrimEx()));\n                _lockedRules[2].ip = Utils.String2List(Utils.Convert2Comma(BlockIP.TrimEx()));\n\n                _lockedItem.ruleSet = Utils.ToJson(_lockedRules, false);\n\n                ConfigHandler.SaveRoutingItem(ref _config, _lockedItem);\n            }\n        }\n\n        #endregion locked\n\n        #region Refresh Save\n\n        public void RefreshRoutingItems()\n        {\n            _routingItems.Clear();\n\n            var routings = LazyConfig.Instance.RoutingItems();\n            foreach (var item in routings)\n            {\n                bool def = false;\n                if (item.id == _config.routingBasicItem.routingIndexId)\n                {\n                    def = true;\n                }\n\n                var it = new RoutingItemModel()\n                {\n                    isActive = def,\n                    ruleNum = item.ruleNum,\n                    id = item.id,\n                    remarks = item.remarks,\n                    url = item.url,\n                    customIcon = item.customIcon,\n                    sort = item.sort,\n                };\n                _routingItems.Add(it);\n            }\n        }\n\n        private void SaveRouting()\n        {\n            _config.routingBasicItem.domainStrategy = domainStrategy;\n            _config.routingBasicItem.enableRoutingAdvanced = enableRoutingAdvanced;\n            _config.routingBasicItem.domainMatcher = domainMatcher;\n            _config.routingBasicItem.domainStrategy4Singbox = domainStrategy4Singbox;\n\n            EndBindingLockedData();\n\n            if (ConfigHandler.SaveConfig(ref _config) == 0)\n            {\n                _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n                _view.DialogResult = true;\n            }\n            else\n            {\n                UI.ShowWarning(ResUI.OperationFailed);\n            }\n        }\n\n        #endregion Refresh Save\n\n        private void RoutingBasicImportRules()\n        {\n            //Extra to bypass the mainland\n            ProxyDomain = \"geosite:google\";\n            DirectDomain = \"geosite:cn\";\n            DirectIP = \"geoip:private,geoip:cn\";\n            BlockDomain = \"geosite:category-ads-all\";\n\n            //_noticeHandler?.Enqueue(ResUI.OperationSuccess);\n            UI.Show(ResUI.OperationSuccess);\n        }\n\n        public void RoutingAdvancedEdit(bool blNew)\n        {\n            RoutingItem item;\n            if (blNew)\n            {\n                item = new();\n            }\n            else\n            {\n                item = LazyConfig.Instance.GetRoutingItem(SelectedSource?.id);\n                if (item is null)\n                {\n                    return;\n                }\n            }\n            var ret = (new RoutingRuleSettingWindow(item)).ShowDialog();\n            if (ret == true)\n            {\n                RefreshRoutingItems();\n                IsModified = true;\n            }\n        }\n\n        public void RoutingAdvancedRemove()\n        {\n            if (SelectedSource is null || SelectedSource.remarks.IsNullOrEmpty())\n            {\n                UI.Show(ResUI.PleaseSelectRules);\n                return;\n            }\n            if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)\n            {\n                return;\n            }\n            foreach (var it in SelectedSources)\n            {\n                var item = LazyConfig.Instance.GetRoutingItem(it?.id);\n                if (item != null)\n                {\n                    ConfigHandler.RemoveRoutingItem(item);\n                }\n            }\n\n            RefreshRoutingItems();\n            IsModified = true;\n        }\n\n        public void RoutingAdvancedSetDefault()\n        {\n            var item = LazyConfig.Instance.GetRoutingItem(SelectedSource?.id);\n            if (item is null)\n            {\n                UI.Show(ResUI.PleaseSelectRules);\n                return;\n            }\n\n            if (ConfigHandler.SetDefaultRouting(ref _config, item) == 0)\n            {\n                RefreshRoutingItems();\n                IsModified = true;\n            }\n        }\n\n        private void RoutingAdvancedImportRules()\n        {\n            if (ConfigHandler.InitBuiltinRouting(ref _config, true) == 0)\n            {\n                RefreshRoutingItems();\n                IsModified = true;\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/SubEditViewModel.cs",
    "content": "﻿using ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.ViewModels\n{\n    public class SubEditViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n        private Window _view;\n\n        [Reactive]\n        public SubItem SelectedSource { get; set; }\n\n        public ReactiveCommand<Unit, Unit> SaveCmd { get; }\n\n        public SubEditViewModel(SubItem subItem, Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n            _view = view;\n\n            if (subItem.id.IsNullOrEmpty())\n            {\n                SelectedSource = subItem;\n            }\n            else\n            {\n                SelectedSource = Utils.DeepCopy(subItem);\n            }\n\n            SaveCmd = ReactiveCommand.Create(() =>\n            {\n                SaveSub();\n            });\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        private void SaveSub()\n        {\n            string remarks = SelectedSource.remarks;\n            if (Utils.IsNullOrEmpty(remarks))\n            {\n                UI.Show(ResUI.PleaseFillRemarks);\n                return;\n            }\n\n            var item = LazyConfig.Instance.GetSubItem(SelectedSource.id);\n            if (item is null)\n            {\n                item = SelectedSource;\n            }\n            else\n            {\n                item.remarks = SelectedSource.remarks;\n                item.url = SelectedSource.url;\n                item.moreUrl = SelectedSource.moreUrl;\n                item.enabled = SelectedSource.enabled;\n                item.profileUpdateInterval = SelectedSource.profileUpdateInterval;\n                item.userAgent = SelectedSource.userAgent;\n                item.sort = SelectedSource.sort;\n                item.filter = SelectedSource.filter;\n                item.convertTarget = SelectedSource.convertTarget;\n            }\n\n            if (ConfigHandler.AddSubItem(ref _config, item) == 0)\n            {\n                _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n                if (_view.IsActive)\n                {\n                    _view.DialogResult = true;\n                }\n                //_view?.Close();\n            }\n            else\n            {\n                _noticeHandler?.Enqueue(ResUI.OperationFailed);\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/SubSettingViewModel.cs",
    "content": "﻿using DynamicData;\nusing DynamicData.Binding;\nusing MaterialDesignThemes.Wpf;\nusing ReactiveUI;\nusing ReactiveUI.Fody.Helpers;\nusing Splat;\nusing System.Reactive;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\nusing v2rayN.Views;\n\nnamespace v2rayN.ViewModels\n{\n    public class SubSettingViewModel : ReactiveObject\n    {\n        private static Config _config;\n        private NoticeHandler? _noticeHandler;\n\n        private IObservableCollection<SubItem> _subItems = new ObservableCollectionExtended<SubItem>();\n        public IObservableCollection<SubItem> SubItems => _subItems;\n\n        [Reactive]\n        public SubItem SelectedSource { get; set; }\n\n        public IList<SubItem> SelectedSources { get; set; }\n\n        public ReactiveCommand<Unit, Unit> SubAddCmd { get; }\n        public ReactiveCommand<Unit, Unit> SubDeleteCmd { get; }\n        public ReactiveCommand<Unit, Unit> SubEditCmd { get; }\n        public ReactiveCommand<Unit, Unit> SubShareCmd { get; }\n        public bool IsModified { get; set; }\n\n        public SubSettingViewModel(Window view)\n        {\n            _config = LazyConfig.Instance.GetConfig();\n            _noticeHandler = Locator.Current.GetService<NoticeHandler>();\n\n            SelectedSource = new();\n\n            RefreshSubItems();\n\n            var canEditRemove = this.WhenAnyValue(\n               x => x.SelectedSource,\n               selectedSource => selectedSource != null && !selectedSource.id.IsNullOrEmpty());\n\n            SubAddCmd = ReactiveCommand.Create(() =>\n            {\n                EditSub(true);\n            });\n            SubDeleteCmd = ReactiveCommand.Create(() =>\n            {\n                DeleteSub();\n            }, canEditRemove);\n            SubEditCmd = ReactiveCommand.Create(() =>\n            {\n                EditSub(false);\n            }, canEditRemove);\n            SubShareCmd = ReactiveCommand.Create(() =>\n            {\n                SubShare();\n            }, canEditRemove);\n\n            Utils.SetDarkBorder(view, _config.uiItem.colorModeDark);\n        }\n\n        public void RefreshSubItems()\n        {\n            _subItems.Clear();\n            _subItems.AddRange(LazyConfig.Instance.SubItems().OrderByDescending(t => t.sort));\n        }\n\n        public void EditSub(bool blNew)\n        {\n            SubItem item;\n            if (blNew)\n            {\n                item = new();\n            }\n            else\n            {\n                item = LazyConfig.Instance.GetSubItem(SelectedSource?.id);\n                if (item is null)\n                {\n                    return;\n                }\n            }\n            var ret = (new SubEditWindow(item)).ShowDialog();\n            if (ret == true)\n            {\n                RefreshSubItems();\n                IsModified = true;\n            }\n        }\n\n        private void DeleteSub()\n        {\n            if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)\n            {\n                return;\n            }\n\n            foreach (var it in SelectedSources)\n            {\n                ConfigHandler.DeleteSubItem(ref _config, it?.id);\n            }\n            RefreshSubItems();\n            _noticeHandler?.Enqueue(ResUI.OperationSuccess);\n            IsModified = true;\n        }\n\n        private async void SubShare()\n        {\n            if (Utils.IsNullOrEmpty(SelectedSource?.url))\n            {\n                return;\n            }\n            var img = QRCodeHelper.GetQRCode(SelectedSource?.url);\n            var dialog = new QrcodeView()\n            {\n                imgQrcode = { Source = img },\n                txtContent = { Text = SelectedSource?.url },\n            };\n\n            await DialogHost.Show(dialog, \"SubDialog\");\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/ViewModels/ViewModelBase.cs",
    "content": "﻿using ReactiveUI;\nusing System;\nusing System.Collections.Generic;\nusing System.ComponentModel;\nusing System.Linq;\nusing System.Runtime.CompilerServices;\nusing System.Text;\nusing System.Threading.Tasks;\n\nnamespace v2rayN.ViewModels\n{\n    public abstract class ViewModelBase : ReactiveObject, INotifyPropertyChanged\n    {\n        public event PropertyChangedEventHandler? PropertyChanged;\n\n        /// <summary>\n        /// Sets property if it does not equal existing value. Notifies listeners if change occurs.\n        /// </summary>\n        /// <typeparam name=\"T\">Type of property.</typeparam>\n        /// <param name=\"member\">The property's backing field.</param>\n        /// <param name=\"value\">The new value.</param>\n        /// <param name=\"propertyName\">Name of the property used to notify listeners.  This\n        /// value is optional and can be provided automatically when invoked from compilers\n        /// that support <see cref=\"CallerMemberNameAttribute\"/>.</param>\n        protected virtual bool SetProperty<T>(ref T member, T value, [CallerMemberName] string? propertyName = null)\n        {\n            if (EqualityComparer<T>.Default.Equals(member, value))\n            {\n                return false;\n            }\n\n            member = value;\n            OnPropertyChanged(propertyName);\n            return true;\n        }\n\n        /// <summary>\n        /// Notifies listeners that a property value has changed.\n        /// </summary>\n        /// <param name=\"propertyName\">Name of the property, used to notify listeners.</param>\n        protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)\n            => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Views/AddServer2Window.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.AddServer2Window\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:Views=\"clr-namespace:v2rayN.Views\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:local=\"clr-namespace:v2rayN\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"HiddifyN\"\n    Width=\"700\"\n    Height=\"500\"\n    x:TypeArguments=\"vms:AddServer2ViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <ScrollViewer\n        materialDesign:ScrollViewerAssist.IsAutoHideEnabled=\"True\"\n        HorizontalScrollBarVisibility=\"Auto\"\n        VerticalScrollBarVisibility=\"Auto\">\n        <Grid Margin=\"8\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n            </Grid.RowDefinitions>\n            <Grid Grid.Row=\"0\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"0\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    Style=\"{StaticResource ModuleTitle}\"\n                    Text=\"{x:Static resx:ResUI.menuServers}\" />\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbRemarks}\" />\n\n                <TextBox\n                    x:Name=\"txtRemarks\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbAddress}\" />\n                <TextBox\n                    x:Name=\"txtAddress\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    IsReadOnly=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n                <StackPanel\n                    Grid.Row=\"2\"\n                    Grid.Column=\"2\"\n                    VerticalAlignment=\"Center\"\n                    Orientation=\"Vertical\">\n                    <Button\n                        x:Name=\"btnBrowse\"\n                        Width=\"100\"\n                        Margin=\"2,0,8,0\"\n                        Content=\"{x:Static resx:ResUI.TbBrowse}\"\n                        Style=\"{StaticResource DefButton}\" />\n                    <Button\n                        x:Name=\"btnEdit\"\n                        Width=\"100\"\n                        Margin=\"2,2,8,0\"\n                        Content=\"{x:Static resx:ResUI.TbEdit}\"\n                        Style=\"{StaticResource DefButton}\" />\n                </StackPanel>\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbCoreType}\" />\n                <ComboBox\n                    x:Name=\"cmbCoreType\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"4\"\n                    HorizontalAlignment=\"Left\"\n                    FontSize=\"{DynamicResource StdFontSize}\"\n                    MaxDropDownHeight=\"1000\"\n                    Style=\"{StaticResource MaterialDesignOutlinedComboBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"4\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbDisplayLog}\" />\n                <StackPanel\n                    Grid.Row=\"4\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    Orientation=\"Horizontal\">\n                    <ToggleButton x:Name=\"togDisplayLog\" HorizontalAlignment=\"Left\" />\n                    <TextBlock\n                        Margin=\"8,0\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"{x:Static resx:ResUI.TipDisplayLog}\" />\n                </StackPanel>\n\n                <TextBlock\n                    Grid.Row=\"5\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbPreSocksPort}\" />\n                <TextBox\n                    x:Name=\"txtPreSocksPort\"\n                    Grid.Row=\"5\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"4\"\n                    HorizontalAlignment=\"Left\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n                <StackPanel\n                    Grid.Row=\"6\"\n                    Grid.Column=\"1\"\n                    Grid.ColumnSpan=\"2\">\n                    <TextBlock\n                        Width=\"500\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"{x:Static resx:ResUI.TipPreSocksPort}\"\n                        TextWrapping=\"Wrap\" />\n                </StackPanel>\n            </Grid>\n\n            <Grid\n                Grid.Row=\"1\"\n                Margin=\"8\"\n                HorizontalAlignment=\"Center\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"200\" />\n                    <ColumnDefinition Width=\"200\" />\n                </Grid.ColumnDefinitions>\n                <Button\n                    x:Name=\"btnSave\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                    Style=\"{StaticResource DefButton}\" />\n                <Button\n                    x:Name=\"btnCancel\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    Click=\"btnCancel_Click\"\n                    Content=\"{x:Static resx:ResUI.TbCancel}\"\n                    IsCancel=\"true\"\n                    Style=\"{StaticResource DefButton}\" />\n            </Grid>\n        </Grid>\n    </ScrollViewer>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/AddServer2Window.xaml.cs",
    "content": "﻿using ReactiveUI;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class AddServer2Window\n    {\n        public AddServer2Window(ProfileItem profileItem)\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            this.Loaded += Window_Loaded;\n            ViewModel = new AddServer2ViewModel(profileItem, this);\n\n            foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))\n            {\n                if (it == ECoreType.v2rayN)\n                    continue;\n                cmbCoreType.Items.Add(it.ToString());\n            }\n            cmbCoreType.Items.Add(string.Empty);\n\n            this.WhenActivated(disposables =>\n            {\n                this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.address, v => v.txtAddress.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.coreType, v => v.cmbCoreType.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.displayLog, v => v.togDisplayLog.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.preSocksPort, v => v.txtPreSocksPort.Text).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.BrowseServerCmd, v => v.btnBrowse).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables);\n            });\n        }\n\n        private void Window_Loaded(object sender, RoutedEventArgs e)\n        {\n            txtRemarks.Focus();\n        }\n\n        private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            if (ViewModel?.IsModified == true)\n            {\n                this.DialogResult = true;\n            }\n            else\n            {\n                this.Close();\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/AddServerWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.AddServerWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuServers}\"\n    Width=\"820\"\n    Height=\"820\"\n    x:TypeArguments=\"vms:AddServerViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <ScrollViewer\n        materialDesign:ScrollViewerAssist.IsAutoHideEnabled=\"True\"\n        HorizontalScrollBarVisibility=\"Auto\"\n        VerticalScrollBarVisibility=\"Auto\">\n        <Grid Margin=\"8\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n            </Grid.RowDefinitions>\n\n            <Grid Grid.Row=\"0\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"0\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource ModuleTitle}\"\n                    Text=\"{x:Static resx:ResUI.menuServers}\" />\n                <StackPanel\n                    Grid.Row=\"0\"\n                    Grid.Column=\"2\"\n                    Orientation=\"Horizontal\">\n                    <ComboBox\n                        x:Name=\"cmbCoreType\"\n                        Width=\"100\"\n                        Margin=\"{StaticResource ServerItemMargin}\"\n                        materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.TbCoreType}\"\n                        Style=\"{StaticResource DefComboBox}\" />\n                </StackPanel>\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbRemarks}\" />\n                <TextBox\n                    x:Name=\"txtRemarks\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbAddress}\" />\n                <TextBox\n                    x:Name=\"txtAddress\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbPort}\" />\n                <TextBox\n                    x:Name=\"txtPort\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Width=\"100\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n            </Grid>\n\n            <Separator\n                Grid.Row=\"1\"\n                Margin=\"0,2\"\n                Style=\"{DynamicResource MaterialDesignSeparator}\" />\n\n            <Grid\n                x:Name=\"gridVMess\"\n                Grid.Row=\"2\"\n                Visibility=\"Hidden\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbId}\" />\n                <TextBox\n                    x:Name=\"txtId\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n                <Button\n                    x:Name=\"btnGUID\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"2\"\n                    Margin=\"4,0\"\n                    Click=\"btnGUID_Click\"\n                    Content=\"{x:Static resx:ResUI.TbGUID}\"\n                    Style=\"{StaticResource DefButton}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbAlterId}\" />\n                <TextBox\n                    x:Name=\"txtAlterId\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"100\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSecurity}\" />\n                <ComboBox\n                    x:Name=\"cmbSecurity\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n            </Grid>\n            <Grid\n                x:Name=\"gridSs\"\n                Grid.Row=\"2\"\n                Visibility=\"Hidden\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbId3}\" />\n                <TextBox\n                    x:Name=\"txtId3\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSecurity3}\" />\n                <ComboBox\n                    x:Name=\"cmbSecurity3\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"300\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n            </Grid>\n            <Grid\n                x:Name=\"gridSocks\"\n                Grid.Row=\"2\"\n                Visibility=\"Hidden\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSecurity4}\" />\n                <TextBox\n                    x:Name=\"txtSecurity4\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbId4}\" />\n                <TextBox\n                    x:Name=\"txtId4\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n            </Grid>\n            <Grid\n                x:Name=\"gridVLESS\"\n                Grid.Row=\"2\"\n                Visibility=\"Hidden\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbId5}\" />\n                <TextBox\n                    x:Name=\"txtId5\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n                <Button\n                    x:Name=\"btnGUID5\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"2\"\n                    Margin=\"4,0\"\n                    Click=\"btnGUID_Click\"\n                    Content=\"{x:Static resx:ResUI.TbGUID}\"\n                    Style=\"{StaticResource DefButton}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbFlow5}\" />\n                <ComboBox\n                    x:Name=\"cmbFlow5\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSecurity5}\" />\n                <TextBox\n                    x:Name=\"txtSecurity5\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n            </Grid>\n            <Grid\n                x:Name=\"gridTrojan\"\n                Grid.Row=\"2\"\n                Visibility=\"Hidden\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbId3}\" />\n                <TextBox\n                    x:Name=\"txtId6\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbFlow5}\" />\n                <ComboBox\n                    x:Name=\"cmbFlow6\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n            </Grid>\n\n            <Separator\n                Grid.Row=\"3\"\n                Margin=\"0,2\"\n                Style=\"{DynamicResource MaterialDesignSeparator}\" />\n\n            <Grid Grid.Row=\"4\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"0\"\n                    Grid.ColumnSpan=\"2\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource ModuleTitle}\"\n                    Text=\"{x:Static resx:ResUI.GbTransport}\" />\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbNetwork}\" />\n                <ComboBox\n                    x:Name=\"cmbNetwork\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"100\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"2\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TipNetwork}\" />\n\n                <TextBlock\n                    x:Name=\"labHeaderType\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbHeaderType}\" />\n                <ComboBox\n                    x:Name=\"cmbHeaderType\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"100\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n                <TextBlock\n                    x:Name=\"tipHeaderType\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"2\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbHeaderType}\" />\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbRequestHost}\" />\n                <TextBox\n                    x:Name=\"txtRequestHost\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n                <TextBlock\n                    x:Name=\"tipRequestHost\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"2\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbRequestHost}\" />\n\n                <TextBlock\n                    Grid.Row=\"4\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbPath}\" />\n                <TextBox\n                    x:Name=\"txtPath\"\n                    Grid.Row=\"4\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefTextBox}\" />\n                <TextBlock\n                    x:Name=\"tipPath\"\n                    Grid.Row=\"4\"\n                    Grid.Column=\"2\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbPath}\" />\n\n                <TextBlock\n                    x:Name=\"lblFragment\"\n                    Grid.Row=\"5\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:Hiddify.Fragment}\" />\n                <ComboBox\n                    x:Name=\"cmbFragment\"\n                    Grid.Row=\"5\"\n                    Grid.Column=\"1\"\n                    Width=\"100\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n               \n            </Grid>\n\n            <Separator\n                Grid.Row=\"5\"\n                Margin=\"0,2\"\n                Style=\"{DynamicResource MaterialDesignSeparator}\" />\n\n            <Grid Grid.Row=\"6\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"0\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbStreamSecurity}\" />\n                <ComboBox\n                    x:Name=\"cmbStreamSecurity\"\n                    Grid.Row=\"0\"\n                    Grid.Column=\"1\"\n                    Width=\"100\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n            </Grid>\n            <Grid\n                x:Name=\"gridTlsMore\"\n                Grid.Row=\"7\"\n                Visibility=\"Hidden\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSNI}\" />\n                <TextBox\n                    x:Name=\"txtSNI\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbFingerprint}\" />\n                <ComboBox\n                    x:Name=\"cmbFingerprint\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    IsEditable=\"True\"\n                    Style=\"{StaticResource DefComboBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbAlpn}\" />\n                <ComboBox\n                    x:Name=\"cmbAlpn\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"4\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbAllowInsecure}\" />\n                <ComboBox\n                    x:Name=\"cmbAllowInsecure\"\n                    Grid.Row=\"4\"\n                    Grid.Column=\"1\"\n                    Width=\"100\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    Style=\"{StaticResource DefComboBox}\" />\n            </Grid>\n            <Grid\n                x:Name=\"gridRealityMore\"\n                Grid.Row=\"7\"\n                Visibility=\"Hidden\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"180\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"0\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSNI}\" />\n                <TextBox\n                    x:Name=\"txtSNI2\"\n                    Grid.Row=\"0\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbFingerprint}\" />\n                <ComboBox\n                    x:Name=\"cmbFingerprint2\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    IsEditable=\"True\"\n                    Style=\"{StaticResource DefComboBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbPublicKey}\" />\n                <TextBox\n                    x:Name=\"txtPublicKey\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbShortId}\" />\n                <TextBox\n                    x:Name=\"txtShortId\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Width=\"200\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"4\"\n                    Grid.Column=\"0\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSpiderX}\" />\n                <TextBox\n                    x:Name=\"txtSpiderX\"\n                    Grid.Row=\"4\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"{StaticResource ServerItemMargin}\"\n                    HorizontalAlignment=\"Left\"\n                    Style=\"{StaticResource DefTextBox}\" />\n            </Grid>\n            <Separator\n                Grid.Row=\"8\"\n                Margin=\"0,2\"\n                Style=\"{DynamicResource MaterialDesignSeparator}\" />\n\n            <Grid\n                Grid.Row=\"9\"\n                Margin=\"8\"\n                HorizontalAlignment=\"Center\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"200\" />\n                    <ColumnDefinition Width=\"200\" />\n                </Grid.ColumnDefinitions>\n                <Button\n                    x:Name=\"btnSave\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                    Cursor=\"Hand\"\n                    Style=\"{StaticResource DefButton}\" />\n                <Button\n                    x:Name=\"btnCancel\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    Click=\"btnCancel_Click\"\n                    Content=\"{x:Static resx:ResUI.TbCancel}\"\n                    Cursor=\"Hand\"\n                    IsCancel=\"true\"\n                    Style=\"{StaticResource DefButton}\" />\n            </Grid>\n        </Grid>\n    </ScrollViewer>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/AddServerWindow.xaml.cs",
    "content": "﻿using ReactiveUI;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing System.Windows.Controls;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class AddServerWindow\n    {\n        public AddServerWindow(ProfileItem profileItem)\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            this.Loaded += Window_Loaded;\n            cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;\n            cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;\n\n            ViewModel = new AddServerViewModel(profileItem, this);\n\n            if (profileItem.configType == EConfigType.VLESS)\n            {\n                Global.coreTypes4VLESS.ForEach(it =>\n                {\n                    cmbCoreType.Items.Add(it);\n                });\n            }\n            else\n            {\n                Global.coreTypes.ForEach(it =>\n                {\n                    cmbCoreType.Items.Add(it);\n                });\n            }\n            cmbCoreType.Items.Add(string.Empty);\n\n            cmbStreamSecurity.Items.Add(string.Empty);\n            cmbStreamSecurity.Items.Add(Global.StreamSecurity);\n\n            Global.networks.ForEach(it =>\n            {\n                cmbNetwork.Items.Add(it);\n            });\n            Global.fingerprints.ForEach(it =>\n            {\n                cmbFingerprint.Items.Add(it);\n                cmbFingerprint2.Items.Add(it);\n            });\n            Global.allowInsecures.ForEach(it =>\n            {\n                cmbAllowInsecure.Items.Add(it);\n            });\n            Global.fragmentStrategies.ForEach(it =>\n            {\n                cmbFragment.Items.Add(it);//hiddify\n            });\n            Global.alpns.ForEach(it =>\n            {\n                cmbAlpn.Items.Add(it);\n            });\n\n            switch (profileItem.configType)\n            {\n                case EConfigType.VMess:\n                    gridVMess.Visibility = Visibility.Visible;\n                    Global.vmessSecuritys.ForEach(it =>\n                    {\n                        cmbSecurity.Items.Add(it);\n                    });\n                    if (profileItem.security.IsNullOrEmpty())\n                    {\n                        profileItem.security = Global.DefaultSecurity;\n                    }\n                    break;\n\n                case EConfigType.Shadowsocks:\n                    gridSs.Visibility = Visibility.Visible;\n                    LazyConfig.Instance.GetShadowsocksSecuritys(profileItem).ForEach(it =>\n                    {\n                        cmbSecurity3.Items.Add(it);\n                    });\n                    break;\n\n                case EConfigType.Socks:\n                    gridSocks.Visibility = Visibility.Visible;\n                    break;\n\n                case EConfigType.VLESS:\n                    gridVLESS.Visibility = Visibility.Visible;\n                    cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);\n                    Global.flows.ForEach(it =>\n                    {\n                        cmbFlow5.Items.Add(it);\n                    });\n                    if (profileItem.security.IsNullOrEmpty())\n                    {\n                        profileItem.security = Global.None;\n                    }\n                    break;\n\n                case EConfigType.Trojan:\n                    gridTrojan.Visibility = Visibility.Visible;\n                    cmbStreamSecurity.Items.Add(Global.StreamSecurityReality);\n                    Global.flows.ForEach(it =>\n                    {\n                        cmbFlow6.Items.Add(it);\n                    });\n                    break;\n            }\n\n            gridTlsMore.Visibility = Visibility.Hidden;\n\n            this.WhenActivated(disposables =>\n            {\n                this.Bind(ViewModel, vm => vm.SelectedSource.coreType, v => v.cmbCoreType.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.address, v => v.txtAddress.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables);\n\n                switch (profileItem.configType)\n                {\n                    case EConfigType.VMess:\n                        this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId.Text).DisposeWith(disposables);\n                        this.Bind(ViewModel, vm => vm.SelectedSource.alterId, v => v.txtAlterId.Text).DisposeWith(disposables);\n                        this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.cmbSecurity.Text).DisposeWith(disposables);\n                        break;\n\n                    case EConfigType.Shadowsocks:\n                        this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId3.Text).DisposeWith(disposables);\n                        this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.cmbSecurity3.Text).DisposeWith(disposables);\n                        break;\n\n                    case EConfigType.Socks:\n                        this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId4.Text).DisposeWith(disposables);\n                        this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity4.Text).DisposeWith(disposables);\n                        break;\n\n                    case EConfigType.VLESS:\n                        this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId5.Text).DisposeWith(disposables);\n                        this.Bind(ViewModel, vm => vm.SelectedSource.flow, v => v.cmbFlow5.Text).DisposeWith(disposables);\n                        this.Bind(ViewModel, vm => vm.SelectedSource.security, v => v.txtSecurity5.Text).DisposeWith(disposables);\n                        break;\n\n                    case EConfigType.Trojan:\n                        this.Bind(ViewModel, vm => vm.SelectedSource.id, v => v.txtId6.Text).DisposeWith(disposables);\n                        this.Bind(ViewModel, vm => vm.SelectedSource.flow, v => v.cmbFlow6.Text).DisposeWith(disposables);\n                        break;\n                }\n                this.Bind(ViewModel, vm => vm.SelectedSource.network, v => v.cmbNetwork.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.headerType, v => v.cmbHeaderType.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.requestHost, v => v.txtRequestHost.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.path, v => v.txtPath.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.fragment, v => v.cmbFragment.Text).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.SelectedSource.streamSecurity, v => v.cmbStreamSecurity.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.sni, v => v.txtSNI.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.allowInsecure, v => v.cmbAllowInsecure.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.fingerprint, v => v.cmbFingerprint.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.alpn, v => v.cmbAlpn.Text).DisposeWith(disposables);\n                //reality\n                this.Bind(ViewModel, vm => vm.SelectedSource.sni, v => v.txtSNI2.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.fingerprint, v => v.cmbFingerprint2.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.publicKey, v => v.txtPublicKey.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.shortId, v => v.txtShortId.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.spiderX, v => v.txtSpiderX.Text).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);\n            });\n\n            this.Title = $\"{profileItem.configType}\";\n        }\n\n        private void Window_Loaded(object sender, RoutedEventArgs e)\n        {\n            txtRemarks.Focus();\n        }\n\n        private void CmbNetwork_SelectionChanged(object sender, SelectionChangedEventArgs e)\n        {\n            SetHeaderType();\n            SetTips();\n        }\n\n        private void CmbStreamSecurity_SelectionChanged(object sender, SelectionChangedEventArgs e)\n        {\n            var security = cmbStreamSecurity.SelectedItem.ToString();\n            if (security == Global.StreamSecurityReality)\n            {\n                gridRealityMore.Visibility = Visibility.Visible;\n                gridTlsMore.Visibility = Visibility.Hidden;\n            }\n            else if (security == Global.StreamSecurity)\n            {\n                gridRealityMore.Visibility = Visibility.Hidden;\n                gridTlsMore.Visibility = Visibility.Visible;\n            }\n            else\n            {\n                gridRealityMore.Visibility = Visibility.Hidden;\n                gridTlsMore.Visibility = Visibility.Hidden;\n            }\n        }\n\n        private void btnGUID_Click(object sender, RoutedEventArgs e)\n        {\n            txtId.Text =\n            txtId5.Text = Utils.GetGUID();\n        }\n\n        private void SetHeaderType()\n        {\n            cmbHeaderType.Items.Clear();\n            \n            var network = cmbNetwork.SelectedItem.ToString();\n            if (Utils.IsNullOrEmpty(network))\n            {\n                cmbHeaderType.Items.Add(Global.None);\n                return;\n            }\n\n            if (network == Global.DefaultNetwork)\n            {\n                cmbHeaderType.Items.Add(Global.None);\n                cmbHeaderType.Items.Add(Global.TcpHeaderHttp);\n            }\n            else if (network is \"kcp\" or \"quic\")\n            {\n                cmbHeaderType.Items.Add(Global.None);\n                Global.kcpHeaderTypes.ForEach(it =>\n                {\n                    cmbHeaderType.Items.Add(it);\n                });\n            }\n            else if (network == \"grpc\")\n            {\n                cmbHeaderType.Items.Add(Global.GrpcgunMode);\n                cmbHeaderType.Items.Add(Global.GrpcmultiMode);\n            }\n            else\n            {\n                cmbHeaderType.Items.Add(Global.None);\n            }\n            cmbHeaderType.SelectedIndex = 0;\n        }\n\n        private void SetTips()\n        {\n            var network = cmbNetwork.SelectedItem.ToString();\n            if (Utils.IsNullOrEmpty(network))\n            {\n                network = Global.DefaultNetwork;\n            }\n            labHeaderType.Visibility = Visibility.Visible;\n            tipRequestHost.Text =\n            tipPath.Text =\n            tipHeaderType.Text = string.Empty;\n            lblFragment.Visibility = cmbFragment.Visibility = Visibility.Hidden;\n            switch (network)\n            {\n                case Global.DefaultNetwork:\n                    tipRequestHost.Text = ResUI.TransportRequestHostTip1;\n                    tipHeaderType.Text = ResUI.TransportHeaderTypeTip1;\n                    break;\n\n                case \"kcp\":\n                    tipHeaderType.Text = ResUI.TransportHeaderTypeTip2;\n                    tipPath.Text = ResUI.TransportPathTip5;\n                    break;\n\n                case \"ws\":\n                    tipRequestHost.Text = ResUI.TransportRequestHostTip2;\n                    tipPath.Text = ResUI.TransportPathTip1;\n                    lblFragment.Visibility = cmbFragment.Visibility = Visibility.Visible;\n                    break;\n\n                case \"h2\":\n                    tipRequestHost.Text = ResUI.TransportRequestHostTip3;\n                    tipPath.Text = ResUI.TransportPathTip2;\n                    break;\n\n                case \"quic\":\n                    tipRequestHost.Text = ResUI.TransportRequestHostTip4;\n                    tipPath.Text = ResUI.TransportPathTip3;\n                    tipHeaderType.Text = ResUI.TransportHeaderTypeTip3;\n                    break;\n\n                case \"grpc\":\n                    tipPath.Text = ResUI.TransportPathTip4;\n                    tipHeaderType.Text = ResUI.TransportHeaderTypeTip4;\n                    labHeaderType.Visibility = Visibility.Hidden;\n                    break;\n            }\n        }\n\n        private void btnCancel_Click(object sender, RoutedEventArgs e)\n        {\n            this.Close();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/DNSSettingWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.DNSSettingWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuDNSSetting}\"\n    Width=\"1000\"\n    Height=\"700\"\n    x:TypeArguments=\"vms:DNSSettingViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <DockPanel Margin=\"8\">\n        <Grid HorizontalAlignment=\"Center\" DockPanel.Dock=\"Bottom\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"200\" />\n                <ColumnDefinition Width=\"200\" />\n            </Grid.ColumnDefinitions>\n            <Button\n                x:Name=\"btnSave\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                Cursor=\"Hand\"\n                Style=\"{StaticResource DefButton}\" />\n            <Button\n                x:Name=\"btnCancel\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                Click=\"btnCancel_Click\"\n                Content=\"{x:Static resx:ResUI.TbCancel}\"\n                Cursor=\"Hand\"\n                IsCancel=\"true\"\n                Style=\"{StaticResource DefButton}\" />\n        </Grid>\n\n        <TabControl HorizontalContentAlignment=\"Left\">\n\n            <TabItem Header=\"{x:Static resx:ResUI.TbSettingsCoreDns}\">\n                <DockPanel Margin=\"{StaticResource SettingItemMargin}\">\n                    <StackPanel DockPanel.Dock=\"Bottom\" Orientation=\"Horizontal\">\n                        <TextBlock\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsDomainStrategy4Freedom}\" />\n                        <ComboBox\n                            x:Name=\"cmbdomainStrategy4Freedom\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            Style=\"{StaticResource DefComboBox}\" />\n                    </StackPanel>\n\n                    <StackPanel DockPanel.Dock=\"Top\" Orientation=\"Horizontal\">\n                        <TextBlock\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsRemoteDNS}\" />\n                        <TextBlock\n                            Margin=\"8,0,0,0\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\">\n                            <Hyperlink Click=\"linkDnsObjectDoc_Click\">\n                                <TextBlock Text=\"{x:Static resx:ResUI.TbDnsObjectDoc}\" />\n                            </Hyperlink>\n                        </TextBlock>\n                        <Button\n                            x:Name=\"btnImportDefConfig4V2ray\"\n                            Margin=\"8,0,0,0\"\n                            Content=\"{x:Static resx:ResUI.TBSettingDnsImportDefConfig}\"\n                            Cursor=\"Hand\"\n                            Style=\"{StaticResource DefButton}\" />\n                    </StackPanel>\n                    <TextBox\n                        x:Name=\"txtnormalDNS\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Stretch\"\n                        AcceptsReturn=\"True\"\n                        BorderThickness=\"1\"\n                        Style=\"{StaticResource DefTextBox}\"\n                        TextWrapping=\"Wrap\"\n                        VerticalScrollBarVisibility=\"Auto\" />\n                </DockPanel>\n            </TabItem>\n\n            <TabItem Header=\"{x:Static resx:ResUI.TbSettingsCoreDnsSingbox}\">\n                <DockPanel Margin=\"{StaticResource SettingItemMargin}\">\n                    <StackPanel DockPanel.Dock=\"Top\" Orientation=\"Horizontal\">\n                        <TextBlock\n                            Margin=\"8,0,0,0\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\">\n                            <Hyperlink Click=\"linkDnsSingboxObjectDoc_Click\">\n                                <TextBlock Text=\"{x:Static resx:ResUI.TbDnsSingboxObjectDoc}\" />\n                            </Hyperlink>\n                        </TextBlock>\n                        <Button\n                            x:Name=\"btnImportDefConfig4Singbox\"\n                            Margin=\"8,0,0,0\"\n                            Content=\"{x:Static resx:ResUI.TBSettingDnsImportDefConfig}\"\n                            Cursor=\"Hand\"\n                            Style=\"{StaticResource DefButton}\" />\n                    </StackPanel>\n                    <TextBox\n                        x:Name=\"txtnormalDNS2\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Stretch\"\n                        AcceptsReturn=\"True\"\n                        BorderThickness=\"1\"\n                        Style=\"{StaticResource DefTextBox}\"\n                        TextWrapping=\"Wrap\"\n                        VerticalScrollBarVisibility=\"Auto\" />\n                </DockPanel>\n            </TabItem>\n\n        </TabControl>\n    </DockPanel>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs",
    "content": "﻿using ReactiveUI;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class DNSSettingWindow\n    {\n        private static Config _config;\n\n        public DNSSettingWindow()\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            _config = LazyConfig.Instance.GetConfig();\n\n            ViewModel = new DNSSettingViewModel(this);\n\n            Global.domainStrategy4Freedoms.ForEach(it =>\n            {\n                cmbdomainStrategy4Freedom.Items.Add(it);\n            });\n\n            this.WhenActivated(disposables =>\n            {\n                this.Bind(ViewModel, vm => vm.domainStrategy4Freedom, v => v.cmbdomainStrategy4Freedom.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.normalDNS, v => v.txtnormalDNS.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.normalDNS2, v => v.txtnormalDNS2.Text).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCmd, v => v.btnImportDefConfig4V2ray).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCmd, v => v.btnImportDefConfig4Singbox).DisposeWith(disposables);\n            });\n        }\n\n        private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e)\n        {\n            Utils.ProcessStart(\"https://www.v2fly.org/config/dns.html#dnsobject\");\n        }\n\n        private void linkDnsSingboxObjectDoc_Click(object sender, RoutedEventArgs e)\n        {\n            Utils.ProcessStart(\"http://sing-box.sagernet.org/zh/configuration/dns/\");\n        }\n\n        private void btnCancel_Click(object sender, RoutedEventArgs e)\n        {\n            this.Close();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.GlobalHotkeySettingWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:Views=\"clr-namespace:v2rayN.Views\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuSetting}\"\n    Width=\"600\"\n    Height=\"500\"\n    x:TypeArguments=\"vms:SubEditViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    KeyDown=\"GlobalHotkeySettingWindow_KeyDown\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <ScrollViewer\n        materialDesign:ScrollViewerAssist.IsAutoHideEnabled=\"True\"\n        HorizontalScrollBarVisibility=\"Auto\"\n        VerticalScrollBarVisibility=\"Auto\">\n        <Grid Margin=\"8\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n            </Grid.RowDefinitions>\n            <Grid x:Name=\"gridText\" Grid.Row=\"0\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"300\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"0\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    Style=\"{StaticResource ModuleTitle}\"\n                    Text=\"{x:Static resx:ResUI.TbGlobalHotkeySetting}\" />\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbDisplayGUI}\" />\n\n                <TextBox\n                    x:Name=\"txtGlobalHotkey0\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    IsReadOnly=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbClearSystemProxy}\" />\n                <TextBox\n                    x:Name=\"txtGlobalHotkey1\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    IsReadOnly=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSetSystemProxy}\" />\n                <TextBox\n                    x:Name=\"txtGlobalHotkey2\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    IsReadOnly=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n                <TextBlock\n                    Grid.Row=\"4\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbNotChangeSystemProxy}\" />\n                <TextBox\n                    x:Name=\"txtGlobalHotkey3\"\n                    Grid.Row=\"4\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    IsReadOnly=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n                <TextBlock\n                    Grid.Row=\"5\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbSystemProxyPac}\" />\n                <TextBox\n                    x:Name=\"txtGlobalHotkey4\"\n                    Grid.Row=\"5\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    IsReadOnly=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n            </Grid>\n\n            <TextBlock\n                Grid.Row=\"1\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.TbGlobalHotkeySettingTip}\" />\n\n            <Grid\n                Grid.Row=\"2\"\n                Margin=\"8\"\n                HorizontalAlignment=\"Center\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"150\" />\n                    <ColumnDefinition Width=\"150\" />\n                    <ColumnDefinition Width=\"150\" />\n                </Grid.ColumnDefinitions>\n                <Button\n                    x:Name=\"btnReset\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    Click=\"btnReset_Click\"\n                    Content=\"{x:Static resx:ResUI.TbReset}\"\n                    Style=\"{StaticResource DefButton}\" />\n                <Button\n                    x:Name=\"btnSave\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    Click=\"btnSave_Click\"\n                    Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                    Style=\"{StaticResource DefButton}\" />\n                <Button\n                    x:Name=\"btnCancel\"\n                    Grid.Column=\"2\"\n                    Margin=\"4\"\n                    Click=\"btnCancel_Click\"\n                    Content=\"{x:Static resx:ResUI.TbCancel}\"\n                    Style=\"{StaticResource DefButton}\" />\n            </Grid>\n        </Grid>\n    </ScrollViewer>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/GlobalHotkeySettingWindow.xaml.cs",
    "content": "﻿using System.Text;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Input;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\n\nnamespace v2rayN.Views\n{\n    public partial class GlobalHotkeySettingWindow\n    {\n        private static Config _config = default!;\n        private Dictionary<object, KeyEventItem> _TextBoxKeyEventItem = default!;\n\n        public GlobalHotkeySettingWindow()\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            _config = LazyConfig.Instance.GetConfig();\n            _config.globalHotkeys ??= new List<KeyEventItem>();\n\n            txtGlobalHotkey0.KeyDown += TxtGlobalHotkey_KeyDown;\n            txtGlobalHotkey1.KeyDown += TxtGlobalHotkey_KeyDown;\n            txtGlobalHotkey2.KeyDown += TxtGlobalHotkey_KeyDown;\n            txtGlobalHotkey3.KeyDown += TxtGlobalHotkey_KeyDown;\n            txtGlobalHotkey4.KeyDown += TxtGlobalHotkey_KeyDown;\n\n            HotkeyHandler.Instance.IsPause = true;\n            this.Closing += (s, e) => HotkeyHandler.Instance.IsPause = false;\n            Utils.SetDarkBorder(this, _config.uiItem.colorModeDark);\n            InitData();\n        }\n\n        private void InitData()\n        {\n            _TextBoxKeyEventItem = new()\n            {\n                { txtGlobalHotkey0,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.ShowForm) },\n                { txtGlobalHotkey1,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyClear) },\n                { txtGlobalHotkey2,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxySet) },\n                { txtGlobalHotkey3,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyUnchanged)},\n                { txtGlobalHotkey4,GetKeyEventItemByEGlobalHotkey(_config.globalHotkeys,EGlobalHotkey.SystemProxyPac)}\n            };\n            BindingData();\n        }\n\n        private void TxtGlobalHotkey_KeyDown(object sender, KeyEventArgs e)\n        {\n            e.Handled = true;\n            var _ModifierKeys = new Key[] { Key.LeftCtrl, Key.RightCtrl, Key.LeftShift,\n                Key.RightShift, Key.LeftAlt, Key.RightAlt, Key.LWin, Key.RWin};\n            _TextBoxKeyEventItem[sender].KeyCode = e.Key == Key.System ? (_ModifierKeys.Contains(e.SystemKey) ? Key.None : e.SystemKey) : (_ModifierKeys.Contains(e.Key) ? Key.None : e.Key);\n            _TextBoxKeyEventItem[sender].Alt = (Keyboard.Modifiers & ModifierKeys.Alt) == ModifierKeys.Alt;\n            _TextBoxKeyEventItem[sender].Control = (Keyboard.Modifiers & ModifierKeys.Control) == ModifierKeys.Control;\n            _TextBoxKeyEventItem[sender].Shift = (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift;\n            (sender as TextBox)!.Text = KeyEventItemToString(_TextBoxKeyEventItem[sender]);\n        }\n\n        private KeyEventItem GetKeyEventItemByEGlobalHotkey(List<KeyEventItem> KELsit, EGlobalHotkey eg)\n        {\n            return Utils.DeepCopy(KELsit.Find((it) => it.eGlobalHotkey == eg) ?? new()\n            {\n                eGlobalHotkey = eg,\n                Control = false,\n                Alt = false,\n                Shift = false,\n                KeyCode = null\n            });\n        }\n\n        private string KeyEventItemToString(KeyEventItem item)\n        {\n            var res = new StringBuilder();\n\n            if (item.Control) res.Append($\"{ModifierKeys.Control}+\");\n            if (item.Shift) res.Append($\"{ModifierKeys.Shift}+\");\n            if (item.Alt) res.Append($\"{ModifierKeys.Alt}+\");\n            if (item.KeyCode != null && item.KeyCode != Key.None)\n                res.Append($\"{item.KeyCode}\");\n\n            return res.ToString();\n        }\n\n        private void BindingData()\n        {\n            foreach (var item in _TextBoxKeyEventItem)\n            {\n                if (item.Value.KeyCode != null && item.Value.KeyCode != Key.None)\n                {\n                    (item.Key as TextBox)!.Text = KeyEventItemToString(item.Value);\n                }\n                else\n                {\n                    (item.Key as TextBox)!.Text = string.Empty;\n                }\n            }\n        }\n\n        private void btnSave_Click(object sender, RoutedEventArgs e)\n        {\n            _config.globalHotkeys = _TextBoxKeyEventItem.Values.ToList();\n\n            if (ConfigHandler.SaveConfig(ref _config, false) == 0)\n            {\n                HotkeyHandler.Instance.ReLoad();\n                this.DialogResult = true;\n            }\n            else\n            {\n                UI.ShowWarning(ResUI.OperationFailed);\n            }\n        }\n\n        private void btnCancel_Click(object sender, RoutedEventArgs e)\n        {\n            this.Close();\n        }\n\n        private void btnReset_Click(object sender, RoutedEventArgs e)\n        {\n            foreach (var k in _TextBoxKeyEventItem.Keys)\n            {\n                _TextBoxKeyEventItem[k].Alt = false;\n                _TextBoxKeyEventItem[k].Control = false;\n                _TextBoxKeyEventItem[k].Shift = false;\n                _TextBoxKeyEventItem[k].KeyCode = Key.None;\n            }\n            BindingData();\n        }\n\n        private void GlobalHotkeySettingWindow_KeyDown(object sender, KeyEventArgs e)\n        {\n            if (e.Key == Key.Escape)\n            {\n                this.Close();\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/HiddifyUI.xaml",
    "content": "﻿<UserControl x:Class=\"v2rayN.Views.HiddifyUI\"\n                     xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"      \n        xmlns:local=\"clr-namespace:v2rayN.Mode\" xmlns:views=\"clr-namespace:v2rayN.Views\"\n             \n        mc:Ignorable=\"d\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"    \nxmlns:conv=\"clr-namespace:v2rayN.Converters\"        \n             d:DesignHeight=\"800\" d:DesignWidth=\"400\">\n\n    <UserControl.Resources>\n        <ResourceDictionary>\n            <ResourceDictionary.MergedDictionaries>\n                <ResourceDictionary Source=\"pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml\" />\n            </ResourceDictionary.MergedDictionaries>\n            <BooleanToVisibilityConverter x:Key=\"BoolToVisConverter\" />\n            <conv:DelayColorConverter x:Key=\"DelayColorConverter\" />\n            <conv:SizeConverter x:Key=\"SizeConverter\" />\n            <conv:LocalizeConverter x:Key=\"LocalizeConverter\" />\n\n        </ResourceDictionary>\n    </UserControl.Resources>\n    <materialDesign:DrawerHost Name=\"NavDrawer\"\n                               IsLeftDrawerOpen=\"{Binding ElementName=MenuToggleButton, Path=IsChecked}\"\n                               LeftDrawerCornerRadius=\"0 20 20 0\"\n                               OpenMode=\"Modal\">\n        <materialDesign:DrawerHost.LeftDrawerContent>\n            <DockPanel MinWidth=\"220\">\n                <DockPanel Margin=\"16\"\n                     DockPanel.Dock=\"Top\"\n                     LastChildFill=\"False\">\n                    <Label>Hi</Label>\n                </DockPanel>\n            </DockPanel>\n        </materialDesign:DrawerHost.LeftDrawerContent>\n\n        <Grid>\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"auto\" />\n                <RowDefinition Height=\"*\" />\n                <RowDefinition Height=\"auto\" />\n            </Grid.RowDefinitions>\n            <materialDesign:ColorZone Padding=\"16\" Name=\"titlebar\"\n                                  materialDesign:ElevationAssist.Elevation=\"Dp0\"\n                                  DockPanel.Dock=\"Top\"\n                                  Mode=\"Standard\">\n                <Grid>\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition Width=\"auto\" />\n                        <ColumnDefinition Width=\"*\" />\n                        <ColumnDefinition Width=\"auto\" />\n                    </Grid.ColumnDefinitions>\n                    <StackPanel Grid.Column=\"0\" Orientation=\"Horizontal\">\n                        <ToggleButton x:Name=\"MenuToggleDarkButton\"\n                            Margin=\"5,0,24,0\"\n                            AutomationProperties.Name=\"HamburgerToggleButton\"\n                            Click=\"MenuToggleButton_Click\"\n                            IsChecked=\"False\"\n                            Style=\"{StaticResource MaterialDesignHamburgerToggleButton}\" />\n                    </StackPanel>\n\n\n\n                    <TextBlock Grid.Column=\"1\"\n                       HorizontalAlignment=\"Center\"\n                       VerticalAlignment=\"Center\"\n                       AutomationProperties.Name=\"Hiddify\"\n                       FontSize=\"22\"\n                       Text=\"Hiddify\" />\n                    <StackPanel Orientation=\"Horizontal\" Grid.Column=\"2\">\n                        <ToggleButton \n                            materialDesign:ToggleButtonAssist.OnContent=\"{materialDesign:PackIcon Kind=WhiteBalanceSunny}\"\n                            Content=\"{materialDesign:PackIcon Kind=NightSky}\"\n                            IsChecked=\"{Binding ColorModeDark}\"\n                            Style=\"{StaticResource MaterialDesignActionToggleButton}\"\n                            ToolTip=\"MaterialDesignActionLightToggleButton\" />\n                        <materialDesign:PopupBox \n                                     PlacementMode=\"BottomAndAlignRightEdges\"\n                                     StaysOpen=\"False\">\n                            <StackPanel>\n                                <Grid Margin=\"10\">\n                                    <Grid.ColumnDefinitions>\n                                        <ColumnDefinition Width=\"Auto\" />\n                                        <ColumnDefinition Width=\"Auto\" />\n                                        <ColumnDefinition Width=\"Auto\" />\n                                    </Grid.ColumnDefinitions>\n                                    <Grid.RowDefinitions>\n                                        <RowDefinition />\n                                        <RowDefinition />\n                                    </Grid.RowDefinitions>\n\n\n\n                                    <Separator />\n\n                                    <ComboBox\n                                        x:Name=\"cmbCurrentLanguage\"\n                                        Grid.Row=\"3\"\n                                        Grid.Column=\"1\"\n                                        Width=\"100\"\n                                        Margin=\"8\"\n                                        materialDesign:HintAssist.Hint=\"Language\"\n                                        SelectedItem=\"{Binding CurrentLanguage}\"\n                                        Style=\"{StaticResource DefComboBox}\" />\n\n                                </Grid>\n                            </StackPanel>\n                        </materialDesign:PopupBox>\n                    </StackPanel>\n\n\n\n                </Grid>\n            </materialDesign:ColorZone>\n\n\n            <Grid Grid.Row=\"1\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"auto\" />\n                    <ColumnDefinition Width=\"*\" />\n                </Grid.ColumnDefinitions>\n\n\n\n                <Grid Grid.Column=\"1\">\n\n\n\n\n                </Grid>\n            </Grid>\n\n\n            <StackPanel Grid.Row=\"1\"\n                HorizontalAlignment=\"Center\"\n                VerticalAlignment=\"Center\">\n                <Button x:Name=\"ConnectVPN\"\n                \n                Width=\"96\"\n                Height=\"96\"\n                materialDesign:ButtonProgressAssist.IsIndeterminate=\"{Binding ConnectProgress}\"\n                materialDesign:ButtonProgressAssist.IsIndicatorVisible=\"{Binding ConnectProgress}\"\n                \n                \n                Background=\"{Binding ConnectColor}\"\n\n                Command=\"{Binding HomeConnectCmd}\"\n                Style=\"{StaticResource MaterialDesignFloatingActionButton}\" \n                Foreground=\"{DynamicResource SecondaryHueMidBrushForeground}\" BorderBrush=\"{x:Null}\">\n\n                    <Image Source=\"/v2rayN.ico\" Width=\"36\" Height=\"36\" />\n\n                </Button>\n                <Label Name=\"connectlbl\" Foreground=\"{Binding ConnectVPNLabelColor}\"  HorizontalAlignment=\"Center\" VerticalAlignment=\"Top\" Grid.Row=\"1\"               \n                Height=\"61\" Width=\"auto\" FontSize=\"18\" Content=\"{Binding ConnectVPNLabel}\" >\n\n                </Label>\n            </StackPanel>\n            <StackPanel Name=\"speedpanel\" \n                Visibility=\"Visible\" \n                Grid.Row=\"1\"\n                HorizontalAlignment=\"Left\"\n                Margin=\"31,0,0,0\"\n                VerticalAlignment=\"Center\"\n                        >\n                <Button\n                    HorizontalAlignment=\"Center\"\n                    Padding=\"0\"\n                    Width=\"36\" \n                    materialDesign:ButtonProgressAssist.IsIndeterminate=\"{Binding DelayProgress}\"\n                materialDesign:ButtonProgressAssist.IsIndicatorVisible=\"{Binding DelayProgress}\"\n                    Command=\"{Binding HomeRealPingServerCmd}\"\n                    Style=\"{StaticResource MaterialDesignFloatingActionButton}\"\n                        Background=\"White\"\n                        BorderBrush=\"White\"\n                        Foreground=\"black\"\n                Height=\"36\">\n                    <materialDesign:PackIcon Kind=\"Speedometer\" Width=\"26\" Height=\"26\" />\n\n                </Button>\n\n\n                <Label  \n                    HorizontalAlignment=\"Center\"                \n                    Height=\"auto\" Width=\"auto\" FontSize=\"12\">\n                    <Label.Content>\n                        <TextBlock>\n                            <TextBlock.Text>\n                                <MultiBinding StringFormat=\"{}{0}: {1}\">\n                                    <Binding Source=\"{x:Static resx:ResUI.HomeDelay}\" />\n                                    <Binding Path=\"SelectedProfileDelay\" />\n                                </MultiBinding>\n                            </TextBlock.Text>\n                        </TextBlock>\n                    </Label.Content>\n                    <!--Delay: 200ms-->\n                </Label>\n            </StackPanel>\n\n\n\n            <materialDesign:Card  Grid.Row=\"1\"\n                VerticalAlignment=\"Top\"\n                                      Margin=\"10\"\n                                      Padding=\"3\"\n                                      UniformCornerRadius=\"4\"\n                                      >\n\n\n\n\n                <Expander  IsExpanded=\"{Binding ProfileExpanded}\" HorizontalAlignment=\"Stretch\" materialDesign:ExpanderAssist.HorizontalHeaderPadding=\"10,2,0,2\" >\n                    <Expander.Header >\n                        <views:MainSubInfoView x:Name=\"SubInfoView\" DataContext=\"{Binding}\"/>\n                    </Expander.Header>\n\n\n                    <ListView Margin=\"12,0,12,0\" Grid.IsSharedSizeScope=\"True\" ItemsSource=\"{Binding SubItems}\" SelectedItem=\"{Binding SelectedSub}\">\n                        <ItemsControl.ItemTemplate>\n                            <DataTemplate>\n                                <views:SubInfoView HorizontalAlignment=\"Stretch\"  />\n\n                            </DataTemplate>\n                        </ItemsControl.ItemTemplate>\n                    </ListView>\n\n\n\n\n\n                </Expander>\n\n\n            </materialDesign:Card>\n            <materialDesign:Card  Grid.Row=\"1\"\n                VerticalAlignment=\"Bottom\" >\n                <StackPanel>\n                    <Expander HorizontalAlignment=\"Stretch\" Header=\"{x:Static resx:ResUI.HomeAdvancedSettings}\" IsExpanded=\"True\">\n                        <StackPanel Margin=\"24,8,24,16\" Orientation=\"Vertical\" TextBlock.Foreground=\"{DynamicResource MaterialDesignBody}\" >\n                            <TextBlock Style=\"{StaticResource MaterialDesignHeadline5TextBlock}\" Visibility=\"Collapsed\">\n                                    Use For\n                            </TextBlock>\n\n                            <ListBox Name=\"lstRouting\" Grid.IsSharedSizeScope=\"True\"\n                                     HorizontalContentAlignment=\"Center\"\n                                     Visibility=\"Collapsed\"\n                                     HorizontalAlignment=\"Stretch\"\n                                     SelectedItem=\"{Binding HomeSelectedRoutingItem}\"\n                                     Style=\"{StaticResource MaterialDesignToolToggleListBox}\">\n\n                                <ListBox.ItemContainerStyle>\n                                    <Style TargetType=\"ListBoxItem\">\n                                        <Setter Property=\"HorizontalAlignment\" Value=\"Stretch\"/>\n                                    </Style>\n                                </ListBox.ItemContainerStyle>\n                                <ListBox.ItemsPanel>\n                                    <ItemsPanelTemplate>\n                                        <UniformGrid Columns=\"3\"/>\n                                    </ItemsPanelTemplate>\n                                </ListBox.ItemsPanel>\n                                <ListBox.ToolTip >\n                                    <StackPanel>\n                                        <TextBlock Text=\"{x:Static resx:ResUI.RoutingAllSites}\"/>\n\n                                    </StackPanel>\n                                </ListBox.ToolTip>\n\n                                <ListBoxItem Content=\"{x:Static resx:ResUI.RoutingBlockedSites}\" />\n                                <ListBoxItem Content=\"{x:Static resx:ResUI.RoutingForeignSites}\"/>\n                                <ListBoxItem Content=\"{x:Static resx:ResUI.RoutingAllSites}\" />\n                            </ListBox>\n\n                            <TextBlock Style=\"{StaticResource MaterialDesignDataGridTextColumnStyle}\" />\n\n                            <TextBlock Style=\"{StaticResource MaterialDesignHeadline5TextBlock}\" Text=\"{x:Static resx:ResUI.HomeProxyModeSelection}\">\n                            </TextBlock>\n\n                            <ListBox Name=\"lstProxyModes\"\n                                     HorizontalAlignment=\"Stretch\"\n                                     HorizontalContentAlignment=\"Center\"\n                                     SelectedItem=\"{Binding HomeSelectedProxyMode}\"\n                                     ItemsSource=\"{Binding ProxyModes}\"\n                                     Style=\"{StaticResource MaterialDesignToolToggleListBox}\">\n                                <ListBox.ItemTemplate>\n                                    <DataTemplate>\n                                        <TextBlock Text=\"{Binding Path=., Converter={StaticResource LocalizeConverter}}\" />\n                                    </DataTemplate>\n                                </ListBox.ItemTemplate>\n                                \n                                <ListBox.ItemContainerStyle>\n                                    <Style TargetType=\"ListBoxItem\">\n                                        <Setter Property=\"HorizontalAlignment\" Value=\"Stretch\"/>\n                                    </Style>\n\n                                </ListBox.ItemContainerStyle>\n                                <ListBox.ItemsPanel>\n                                    <ItemsPanelTemplate>\n                                        <UniformGrid Columns=\"3\"/>\n                                    </ItemsPanelTemplate>\n                                </ListBox.ItemsPanel>\n                                <ListBox.ToolTip >\n                                    <StackPanel>\n                                        <TextBlock Text=\"{x:Static resx:ResUI.RoutingAllSites}\"/>\n\n                                    </StackPanel>\n                                </ListBox.ToolTip>\n                                  \n<!--\n                                <ListBoxItem Content=\"{x:Static resx:ResUI.HomeProxyAuto}\" IsSelected=\"True\" />\n                                <ListBoxItem Content=\"{x:Static resx:ResUI.HomeProxyLoadBalance}\"/>\n                                <ListBoxItem Content=\"{x:Static resx:ResUI.HomeProxyManual}\" />\n                                -->\n                            </ListBox>\n                            <TextBlock Style=\"{StaticResource MaterialDesignHelperTextBlock}\" />\n                        </StackPanel>\n                    </Expander>\n\n                </StackPanel>\n            </materialDesign:Card>\n            <materialDesign:Snackbar x:Name=\"MainSnackbar\"\n                                         \n                                     Grid.Row=\"0\"\n                                     MessageQueue=\"{materialDesign:MessageQueue}\" />\n            <materialDesign:Card x:Name=\"NotificationPanel\"\n                                 Grid.Row=\"0\"\n                                 Grid.RowSpan=\"2\"\n                                 Margin=\"0,10,10,0\"\n                                         \n                                 HorizontalAlignment=\"Right\"\n                                 VerticalAlignment=\"Top\"\n                                 UniformCornerRadius=\"25\">\n                <Grid Visibility=\"Collapsed\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition Height=\"auto\" />\n                        <RowDefinition Height=\"*\" />\n                        <RowDefinition Height=\"auto\" />\n                    </Grid.RowDefinitions>\n                    <Button Grid.Row=\"0\"\n                        HorizontalAlignment=\"Right\"\n                        Click=\"CloseNotificationPanel_Click\"\n                        Content=\"{materialDesign:PackIcon Kind=Close}\"\n                        Style=\"{StaticResource MaterialDesignIconForegroundButton}\" />\n                    <TextBlock Grid.Row=\"1\"\n                           Margin=\"0,0,0,20\"\n                           FontSize=\"18\"\n                           Text=\"{Binding DemoItems[0].Notifications, StringFormat=You have \\{0\\} new notifications!}\"\n                           TextAlignment=\"Center\"\n                           TextWrapping=\"Wrap\" />\n                    <StackPanel Grid.Row=\"2\"\n                            Margin=\"10\"\n                            HorizontalAlignment=\"Right\"\n                            Orientation=\"Horizontal\">\n                        <RepeatButton Margin=\"0,0,10,0\"\n                                materialDesign:ButtonAssist.CornerRadius=\"16\"\n                                Command=\"{Binding AddNewNotificationCommand}\"\n                                Content=\"Add New Notification\"\n                                Style=\"{StaticResource MaterialDesignFlatButton}\" />\n                        <Button materialDesign:ButtonAssist.CornerRadius=\"16\"\n                          Command=\"{Binding DismissAllNotificationsCommand}\"\n                          Content=\"Dismiss All\"\n                          Style=\"{StaticResource MaterialDesignFlatMidBgButton}\" />\n                    </StackPanel>\n\n                </Grid>\n            </materialDesign:Card>\n        </Grid>\n\n    </materialDesign:DrawerHost>\n</UserControl>\n"
  },
  {
    "path": "v2rayN/v2rayN/Views/HiddifyUI.xaml.cs",
    "content": "﻿using MaterialDesignThemes.Wpf;\nusing ReactiveUI;\nusing System;\nusing System.Collections.Generic;\nusing System.Diagnostics;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Navigation;\nusing System.Windows.Shapes;\nusing v2rayN.Resx;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    /// <summary>\n    /// Interaction logic for HiddifyUI.xaml\n    /// </summary>\n    public partial class HiddifyUI : UserControl\n    {\n        public static Snackbar Snackbar = new();\n        public bool ShowTitleBar { \n            get => titlebar.Visibility == Visibility.Visible;\n            set {\n                titlebar.Visibility = value ? Visibility.Visible : Visibility.Collapsed;\n            } \n        }\n            \n        \n        public HiddifyUI()\n        {\n            InitializeComponent();\n            //FlowDirection = FlowDirection.RightToLeft;\n            Task.Factory.StartNew(() => Thread.Sleep(2500)).ContinueWith(t =>\n            {\n                //note you can use the message queue from any thread, but just for the demo here we \n                //need to get the message queue from the snackbar, so need to be on the dispatcher\n                MainSnackbar.MessageQueue?.Enqueue(ResUI.HomeWelcomeMsg);\n            }, TaskScheduler.FromCurrentSynchronizationContext());\n\n\n            Global.Languages.ForEach(it =>\n            {\n                cmbCurrentLanguage.Items.Add(it);\n            });\n            \n            ModifyTheme(false);\n            \n        }\n        private void OnCopy(object sender, ExecutedRoutedEventArgs e)\n        {\n            if (e.Parameter is string stringValue)\n            {\n                try\n                {\n                    Clipboard.SetDataObject(stringValue);\n                }\n                catch (Exception ex)\n                {\n                    Trace.WriteLine(ex.ToString());\n                }\n            }\n        }\n\n        private void MenuToggleButton_Click(object sender, RoutedEventArgs e)\n        {\n\n        }\n\n        private void MenuDarkModeButton_Click(object sender, RoutedEventArgs e)\n        {\n\n                   // => ModifyTheme(DarkModeToggleButton.IsChecked == true);\n        }\n\n        private static void ModifyTheme(bool isDarkTheme)\n        {\n            var paletteHelper = new PaletteHelper();\n            var theme = paletteHelper.GetTheme();\n\n            theme.SetBaseTheme(isDarkTheme ? Theme.Dark : Theme.Light);\n            paletteHelper.SetTheme(theme);\n        }\n\n        private void DarkModeToggleButton_Click(object sender, RoutedEventArgs e)\n        {\n\n        }\n\n        private void DarkModeToggleButton_Click_1(object sender, RoutedEventArgs e)\n        {\n\n        }\n        private void CloseNotificationPanel_Click(object sender, RoutedEventArgs e) => NotificationPanel.Visibility = Visibility.Collapsed;\n\n        private void FAB_Click(object sender, RoutedEventArgs e)\n        {\n\n        }\n\n        private void ConnectVPN_Click(object sender, RoutedEventArgs e)\n        {\n\n            ConnectVPN.Background = new SolidColorBrush(Color.FromRgb(0xFF, 0xF2, 0x67));\n            //((HomeWindowViewModel)DataContext).ConnectProgress = true;\n            connectlbl.Content = \"Connecting...\";\n            Task.Factory.StartNew(() => Thread.Sleep(2500)).ContinueWith(t =>\n            {\n                speedpanel.Visibility = Visibility.Visible;\n                //((ViewModels.HiddifyUIViewModel)DataContext).ConnectProgress = false;\n                ConnectVPN.Background = new SolidColorBrush(Colors.LightGreen);\n                connectlbl.Content = \"Connected Successfully\";\n            }, TaskScheduler.FromCurrentSynchronizationContext());\n\n            //var xx = this.DataContext as MainWindowViewModel;\n            //Console.WriteLine();\n        }\n\n        private void NewProfile_Click(object sender, RoutedEventArgs e)\n        {\n            MessageBox.Show(\"Going to User Page\");\n        }\n\n\n        private void ActiveProfile_PreviewMouseDown(object sender, MouseButtonEventArgs e)\n        {\n            MessageBox.Show(\"Going to User Page\");\n        }\n\n        private void UpdateUsage_Click(object sender, RoutedEventArgs e)\n        {\n            MessageBox.Show(\"Updateing Usage\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Views/MainSubInfoView.xaml",
    "content": "﻿<UserControl x:Class=\"v2rayN.Views.MainSubInfoView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                 xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n             xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:local=\"clr-namespace:v2rayN.Views\"\n             xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"450\" d:DesignWidth=\"800\">\n    <UserControl.Resources>\n        <ResourceDictionary>\n            <ResourceDictionary.MergedDictionaries>\n                <ResourceDictionary Source=\"pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml\" />\n            </ResourceDictionary.MergedDictionaries>\n            <BooleanToVisibilityConverter x:Key=\"BoolToVisConverter\" />\n            <conv:DelayColorConverter x:Key=\"DelayColorConverter\" />\n            <conv:SizeConverter x:Key=\"SizeConverter\" />\n\n        </ResourceDictionary>\n    </UserControl.Resources>\n\n    <StackPanel  HorizontalAlignment=\"Stretch\"  >\n        <Grid>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"*\" />\n                <ColumnDefinition Width=\"auto\" />\n            </Grid.ColumnDefinitions>\n            <StackPanel Orientation=\"Horizontal\">\n                <TextBlock  \n                VerticalAlignment=\"Center\" \n                TextTrimming=\"CharacterEllipsis\" \n                MaxWidth=\"200\"\n                Style=\"{StaticResource MaterialDesignHeadline5TextBlock}\" Text=\"{Binding SelectedSub.remarks}\" >\n\n                </TextBlock>\n                <Button Name=\"GotoProfile\"\n                        Visibility=\"Collapsed\"\n                    Command=\"{Binding HomeGotoProfileCmd}\"\n                     Background=\"{x:Null}\" BorderBrush=\"{x:Null}\"\n                    \n                        Style=\"{StaticResource MaterialDesignFlatButton}\"\n                    >\n                    <materialDesign:PackIcon Kind=\"OpenInNew\"  />\n                </Button>\n                <Button Name=\"Delete\"  \n                                                Background=\"{x:Null}\"\n                                    Style=\"{StaticResource MaterialDesignFlatButton}\"\n                                                Command=\"{Binding HomeDeleteSubCmd}\"\n                                                BorderBrush=\"{x:Null}\" >\n                    <StackPanel Orientation=\"Horizontal\" >\n                        <!--<TextBlock Text=\"{x:Static resx:ResUI.HomeDelete}\">\n\n                            </TextBlock>-->\n                        <materialDesign:PackIcon Kind=\"TrashCanOutline\" VerticalAlignment=\"Center\" Margin=\"2,0,0,0\"  />\n\n                    </StackPanel>\n                </Button>\n            </StackPanel>\n            <Button Name=\"NewProfile\" Grid.Column=\"1\"\n                                            Padding=\"0\"\n                                                VerticalAlignment=\"Center\"  Height=\"36\" materialDesign:ButtonAssist.CornerRadius=\"8\" \n                                                Background=\"{x:Null}\"\n                                                Command=\"{Binding HomeNewProfileCmd}\"\n                    Style=\"{StaticResource MaterialDesignFlatButton}\"\n                                                BorderBrush=\"{x:Null}\" >\n                <StackPanel Orientation=\"Horizontal\" >\n                    <materialDesign:PackIcon Kind=\"Plus\" VerticalAlignment=\"Center\"  />\n                    <TextBlock Style=\"{StaticResource MaterialDesignBody1TextBlock}\"\n                        Text=\"{x:Static resx:ResUI.HomeImport}\"\n                               >\n                    </TextBlock>\n\n                </StackPanel>\n            </Button>\n        </Grid>\n\n\n        <Grid Visibility=\"{Binding SelectedSub.sub_info_visible}\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"auto\" />\n                <ColumnDefinition Width=\"*\" />\n            </Grid.ColumnDefinitions>\n\n            <StackPanel Margin=\"0,0,20,0\">\n                <TextBlock HorizontalAlignment=\"Center\" Style=\"{StaticResource MaterialDesignBody1TextBlock}\">\n                    <TextBlock.Text>\n                        <MultiBinding StringFormat=\"{}{0} {1}\">\n                            <Binding Path=\"SelectedSub.remaningExpireDays\" />\n                            <Binding Source=\"{x:Static resx:ResUI.HomeDays}\" />\n                        </MultiBinding>\n                    </TextBlock.Text>\n                </TextBlock>\n                <Label HorizontalAlignment=\"Center\" Content=\"{x:Static resx:ResUI.HomeRemaining}\"></Label>\n            </StackPanel>\n\n            <StackPanel Grid.Column=\"1\">\n\n                <Grid >\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition Width=\"auto\" />\n                        <ColumnDefinition Width=\"*\" />\n                    </Grid.ColumnDefinitions>\n\n\n                    <Button Name=\"UpdateUsage\" Grid.Column=\"0\" HorizontalAlignment=\"Left\"\n                                                VerticalAlignment=\"Bottom\"  Padding=\"0\" materialDesign:ButtonAssist.CornerRadius=\"8\" \n                                                Background=\"{x:Null}\"\n                                                Command=\"{Binding HomeUpdateUsageCmd}\"\n                                                BorderBrush=\"{x:Null}\" Foreground=\"#FF0E0808\">\n                        <StackPanel Orientation=\"Horizontal\" >\n                            <TextBlock Text=\"{x:Static resx:ResUI.HomeUsage}\">\n\n                            </TextBlock>\n                            <materialDesign:PackIcon Kind=\"Refresh\" VerticalAlignment=\"Center\" Margin=\"2,0,0,0\"  />\n\n                        </StackPanel>\n                    </Button>\n\n                    \n\n                    <Label Grid.Column=\"1\" HorizontalAlignment=\"Right\" VerticalAlignment=\"Bottom\">\n                        <Label.Content>\n                            <TextBlock>\n                                <TextBlock.Text>\n                                    <MultiBinding StringFormat=\"{}{0}/{1}\">\n                                        <Binding Path=\"SelectedSub.usage\" Converter=\"{StaticResource SizeConverter}\"/>\n                                        <Binding Path=\"SelectedSub.total\" Converter=\"{StaticResource SizeConverter}\"/>\n                                    </MultiBinding>\n                                </TextBlock.Text>\n                            </TextBlock>\n                        </Label.Content>\n                    </Label>\n                </Grid>\n                <!--TODO: @hiddify1; Fix this progress bar-->\n                <ProgressBar Height=\"10\" Value=\"{Binding SelectedSub.usage}\" Maximum=\"{Binding SelectedSub.total}\" HorizontalAlignment=\"Stretch\" />\n            </StackPanel>\n        </Grid>\n    </StackPanel>\n</UserControl>\n"
  },
  {
    "path": "v2rayN/v2rayN/Views/MainSubInfoView.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Navigation;\nusing System.Windows.Shapes;\n\nnamespace v2rayN.Views\n{\n    /// <summary>\n    /// Interaction logic for MainSubInfoView.xaml\n    /// </summary>\n    public partial class MainSubInfoView : UserControl\n    {\n        public MainSubInfoView()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Views/MainWindow.xaml",
    "content": "<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.MainWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:base=\"clr-namespace:v2rayN.Base\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:local=\"clr-namespace:v2rayN.Views\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:tb=\"clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    \n    Title=\"HiddifyN\"\n    Width=\"{Binding WindowWidth, Mode=TwoWay}\"\n    Height=\"700\"\n    MinWidth=\"420\"\n    MaxWidth=\"{Binding MaxWindowWidth, Mode=TwoWay}\"\n    MinHeight=\"600\"\n    x:TypeArguments=\"vms:MainWindowViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ShowInTaskbar=\"True\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <Window.Resources>\n        <ResourceDictionary>\n            <ResourceDictionary.MergedDictionaries>\n                <ResourceDictionary Source=\"pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml\" />\n            </ResourceDictionary.MergedDictionaries>\n            <BooleanToVisibilityConverter x:Key=\"BoolToVisConverter\" />\n            <conv:DelayColorConverter x:Key=\"DelayColorConverter\" />\n            <conv:SizeConverter x:Key=\"SizeConverter\" />\n            <conv:LocalizeConverter x:Key=\"LocalizeConverter\" />\n\n        </ResourceDictionary>\n    </Window.Resources>\n    \n    <materialDesign:DialogHost\n        Identifier=\"RootDialog\"\n        SnackbarMessageQueue=\"{Binding ElementName=MainSnackbar, Path=MessageQueue}\"\n        IsOpen=\"{Binding Loading}\"\n        Style=\"{StaticResource MaterialDesignEmbeddedDialogHost}\">\n        <materialDesign:DialogHost.DialogContent >\n            <materialDesign:Card\n  Padding=\"4\"\n  UniformCornerRadius=\"14\">\n                <ProgressBar\n    IsIndeterminate=\"True\"\n    Style=\"{StaticResource MaterialDesignCircularProgressBar}\"\n    Value=\"50\" />\n            </materialDesign:Card>\n            \n        </materialDesign:DialogHost.DialogContent>\n        <Grid>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"400\" />\n                <ColumnDefinition Width=\"auto\" />\n                <ColumnDefinition Width=\"*\" />\n\n            </Grid.ColumnDefinitions>\n\n            <local:HiddifyUI DataContext=\"{Binding}\" x:Name=\"HiddifyUI\" Grid.Column=\"0\"/>\n\n            <GridSplitter Grid.Column=\"1\" ResizeDirection=\"Columns\" \n                  Width=\"5\" Visibility=\"Collapsed\"\n                  VerticalAlignment=\"Stretch\" \n                  HorizontalAlignment=\"Center\" />\n            <Grid Grid.Column=\"2\" >\n                <DockPanel Name=\"V2rayNPanel\" Visibility=\"{Binding V2RayNPanelVisible, Converter={StaticResource BoolToVisConverter}}\">\n                    <ToolBarTray DockPanel.Dock=\"Top\">\n                        <ToolBar\n                        HorizontalAlignment=\"Stretch\"\n                        VerticalAlignment=\"Stretch\"\n                        ClipToBounds=\"True\"\n                        \n                        Style=\"{StaticResource MaterialDesignToolBar}\">\n\n\n                            <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\" >\n                                <MenuItem\n                                x:Name=\"menuRouting\"\n                                Padding=\"8,0\">\n                                    <MenuItem.Header>\n                                        <ComboBox\n                                x:Name=\"cmbRoutings2\"\n                                MaxWidth=\"0\"\n                                Width=\"0\"\n                                Margin=\"8,0\"\n                                materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.menuRouting}\"\n                                DisplayMemberPath=\"remarks\"\n                                FontSize=\"{DynamicResource StdFontSize}\"\n                                Style=\"{StaticResource MaterialDesignFloatingHintComboBox}\" />\n                                    </MenuItem.Header>\n                                </MenuItem>\n                            </Menu>\n\n                            <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\" Visibility=\"Collapsed\">\n                                <StackPanel HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" Orientation=\"Horizontal\">\n                                    <TextBlock Text=\"{x:Static resx:ResUI.TbEnableProxy}\" VerticalAlignment=\"Center\" />\n\n\n                                    <ToggleButton Margin=\"8,3,0,0\"\n                                x:Name=\"togEnableProxy\"\n                                IsChecked=\"{Binding SysProxyState}\"\n                                Click=\"togEnableProxy_Click\">\n                                    </ToggleButton>\n                                </StackPanel>\n\n                            </Menu>\n                            <Separator />\n\n                            <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\">\n                                <MenuItem Padding=\"8,0\">\n                                    <MenuItem.Header>\n                                        <StackPanel Orientation=\"Horizontal\">\n                                            <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"SettingsOutline\" />\n                                            <TextBlock Text=\"{x:Static resx:ResUI.menuSetting}\" />\n                                        </StackPanel>\n                                    </MenuItem.Header>\n                                    <MenuItem\n                                    x:Name=\"menuOptionSetting\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuOptionSetting}\" />\n                                    <MenuItem\n                                    x:Name=\"menuRoutingSetting\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRoutingSetting}\" />\n                                    <MenuItem\n                                    x:Name=\"menuDNSSetting\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuDNSSetting}\" />\n                                    <MenuItem\n                                    x:Name=\"menuGlobalHotkeySetting\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuGlobalHotkeySetting}\" />\n                                    <Separator Margin=\"-40,5\" />\n                                    <MenuItem\n                                    x:Name=\"menuRebootAsAdmin\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRebootAsAdmin}\" />\n                                    <MenuItem\n                                    x:Name=\"menuSettingsSetUWP\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Click=\"menuSettingsSetUWP_Click\"\n                                    Header=\"{x:Static resx:ResUI.TbSettingsSetUWP}\" />\n                                    <MenuItem\n                                    x:Name=\"menuClearServerStatistics\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuClearServerStatistics}\" />\n                                    <Separator Margin=\"-40,5\" />\n                                    <MenuItem\n                                    x:Name=\"menuImportOldGuiConfig\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuImportOldGuiConfig}\" />\n                                </MenuItem>\n                            </Menu>\n                            <Separator />\n                            <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\">\n                                <MenuItem x:Name=\"menuReload\" Padding=\"8,0\">\n                                    <MenuItem.Header>\n                                        <StackPanel Orientation=\"Horizontal\">\n                                            <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"Reload\" />\n                                            <TextBlock Text=\"{x:Static resx:ResUI.menuReload}\" />\n                                        </StackPanel>\n                                    </MenuItem.Header>\n                                </MenuItem>\n                            </Menu>\n                            <Separator />\n\n                            <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\" >\n                                <MenuItem\n                                x:Name=\"menuPromotion\"\n                                Padding=\"8,0\"\n                                Click=\"menuPromotion_Click\">\n                                    <MenuItem.Header>\n                                        <StackPanel Orientation=\"Horizontal\">\n                                            <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"VolumeHigh\" />\n                                            <TextBlock Text=\"{x:Static resx:ResUI.menuPromotion}\" />\n                                        </StackPanel>\n                                    </MenuItem.Header>\n                                </MenuItem>\n                            </Menu>\n\n                            \n\n                                \n                                    \n                                    <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\">\n                                        <MenuItem Padding=\"8,0\">\n                                            <MenuItem.Header>\n                                                <StackPanel Orientation=\"Horizontal\">\n                                                    <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"Update\" />\n                                                    <TextBlock Text=\"{x:Static resx:ResUI.menuCheckUpdate}\" />\n                                                </StackPanel>\n                                            </MenuItem.Header>\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateN\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"HiddifyN\" />\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateV2flyCore\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"V2fly v5 Core\" />\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateSagerNetCore\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"SagerNet Core\" />\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateXrayCore\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"Hiddify Xray Core\" />\n                                            <Separator Margin=\"-40,5\" />\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateClashCore\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"Clash Core\" />\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateClashMetaCore\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"Clash.Meta Core\" />\n                                            <Separator Margin=\"-40,5\" />\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateSingBoxCore\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"Sing-box Core\" />\n                                            <Separator Margin=\"-40,5\" />\n                                            <MenuItem\n                                    x:Name=\"menuCheckUpdateGeo\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"Geo files\" />\n                                        </MenuItem>\n                                    </Menu>\n\n                                    <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\">\n                                        <MenuItem x:Name=\"menuHelp\" Padding=\"8,0\">\n                                            <MenuItem.Header>\n                                                <StackPanel Orientation=\"Horizontal\">\n                                                    <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"HelpCircleOutline\" />\n                                                    <TextBlock Text=\"{x:Static resx:ResUI.menuHelp}\" />\n                                                </StackPanel>\n                                            </MenuItem.Header>\n                                        </MenuItem>\n                                    </Menu>\n                            <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\">\n                                <MenuItem\n                                x:Name=\"menuClose\"\n                                Padding=\"8,0\"\n                                Click=\"menuClose_Click\">\n                                    <MenuItem.Header>\n                                        <StackPanel Orientation=\"Horizontal\">\n                                            <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"Minimize\" />\n                                            <TextBlock Text=\"{x:Static resx:ResUI.menuClose}\" />\n                                        </StackPanel>\n                                    </MenuItem.Header>\n                                </MenuItem>\n                            </Menu>\n\n\n                        </ToolBar>\n                    </ToolBarTray>\n                    <WrapPanel Margin=\"2\" DockPanel.Dock=\"Top\">\n                        <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\">\n                            <MenuItem Padding=\"8,0\">\n                                <MenuItem.Header>\n                                    <StackPanel Orientation=\"Horizontal\">\n                                        <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"Server\" />\n                                        <TextBlock Text=\"{x:Static resx:ResUI.menuServers}\" />\n                                    </StackPanel>\n                                </MenuItem.Header>\n                                <MenuItem\n                                    x:Name=\"menuAddCustomServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddCustomServer}\" />\n                                <Separator Margin=\"-40,5\" />\n                                <MenuItem\n                                    x:Name=\"menuAddVmessServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddVmessServer}\" />\n                                <MenuItem\n                                    x:Name=\"menuAddVlessServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddVlessServer}\" />\n                                <MenuItem\n                                    x:Name=\"menuAddShadowsocksServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddShadowsocksServer}\" />\n                                <MenuItem\n                                    x:Name=\"menuAddSocksServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddSocksServer}\" />\n                                <MenuItem\n                                    x:Name=\"menuAddTrojanServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddTrojanServer}\" />\n                                <Separator Margin=\"-40,5\" />\n                                <MenuItem\n                                    x:Name=\"menuAddServerViaClipboard\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddServerViaClipboard}\" />\n                                <MenuItem\n                                    x:Name=\"menuAddServerViaScan\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuAddServerViaScan}\" />\n\n                            </MenuItem>\n                        </Menu>\n                        <Menu Margin=\"0,1\" Style=\"{StaticResource ToolbarMenu}\">\n                            <MenuItem Padding=\"8,0\" x:Name=\"menuSubSetting\">\n                                <MenuItem.Header>\n                                    <StackPanel Orientation=\"Horizontal\">\n                                        <materialDesign:PackIcon\n                                            Margin=\"0,0,8,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"BookClockOutline\" />\n                                        <TextBlock Text=\"{x:Static resx:ResUI.menuSubscription}\" />\n                                    </StackPanel>\n                                </MenuItem.Header>\n                            </MenuItem>\n\n                        </Menu>\n                        <Separator />\n                        <ListBox\n                        x:Name=\"lstGroup\"\n                        FontSize=\"{DynamicResource StdFontSize}\"\n                        ItemContainerStyle=\"{StaticResource MyChipListBoxItem}\"\n                        VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\"\n                        Style=\"{StaticResource MaterialDesignChoiceChipPrimaryOutlineListBox}\">\n                            <ListBox.ItemTemplate>\n                                <DataTemplate>\n                                    <StackPanel Orientation=\"Horizontal\"  VerticalAlignment=\"Center\" HorizontalAlignment=\"Center\">\n                                        <MenuItem Padding=\"8,0\" Click=\"update_sub_click\" Uid=\"{Binding id}\" >\n                                            <MenuItem.Header>\n                                                <StackPanel Orientation=\"Horizontal\">\n                                                    <materialDesign:PackIcon\n                                            Margin=\"0,0,0,0\"\n                                            VerticalAlignment=\"Center\"\n                                            Kind=\"Update\" />\n                                                </StackPanel>\n                                            </MenuItem.Header>\n                                        </MenuItem>\n                                        <TextBlock Text=\"{Binding remarks}\" VerticalAlignment=\"Center\"/>\n\n                                    </StackPanel>\n                                </DataTemplate>\n                            </ListBox.ItemTemplate>\n                        </ListBox>\n\n                        <Button\n                        x:Name=\"btnAddSub\"\n                        Width=\"30\"\n                        Height=\"30\"\n                        Margin=\"4,0\"\n                        Style=\"{StaticResource MaterialDesignFloatingActionMiniLightButton}\">\n                            <materialDesign:PackIcon VerticalAlignment=\"Center\" Kind=\"Plus\" />\n                        </Button>\n                        <Button\n                        x:Name=\"btnAutofitColumnWidth\"\n                        Width=\"30\"\n                        Height=\"30\"\n                        Margin=\"4,0\"\n                        Style=\"{StaticResource MaterialDesignFloatingActionMiniLightButton}\">\n                            <materialDesign:PackIcon VerticalAlignment=\"Center\" Kind=\"ArrowSplitVertical\" />\n                        </Button>\n                        <TextBox\n                        x:Name=\"txtServerFilter\"\n                        Width=\"200\"\n                        Margin=\"4,0\"\n                        VerticalContentAlignment=\"Center\"\n                        materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.MsgServerTitle}\"\n                        materialDesign:TextFieldAssist.HasClearButton=\"True\"\n                        Style=\"{StaticResource DefTextBox}\" />\n                    </WrapPanel>\n\n                    <materialDesign:ColorZone\n                    Height=\"50\"\n                    DockPanel.Dock=\"Bottom\"\n                    Mode=\"Standard\">\n                        <DockPanel>\n                            <StackPanel\n                            Margin=\"8,0\"\n                            VerticalAlignment=\"Center\"\n                            DockPanel.Dock=\"Right\">\n                                <TextBlock x:Name=\"txtSpeedProxyDisplay\" Style=\"{StaticResource StatusbarItem}\" />\n                                <Border Margin=\"2\" />\n                                <TextBlock x:Name=\"txtSpeedDirectDisplay\" Style=\"{StaticResource StatusbarItem}\" />\n                            </StackPanel>\n\n                            <StackPanel\n                            Width=\"240\"\n                            Margin=\"8,0\"\n                            VerticalAlignment=\"Center\"\n                            DockPanel.Dock=\"Left\">\n                                <TextBlock x:Name=\"txtInboundDisplay\" Style=\"{StaticResource StatusbarItem}\" />\n                                <Border Margin=\"2\" />\n                                <TextBlock x:Name=\"txtInboundLanDisplay\" Style=\"{StaticResource StatusbarItem}\" />\n                            </StackPanel>\n\n                            <StackPanel\n                            x:Name=\"spEnableTun\"\n                            Width=\"auto\"\n                            Margin=\"8,0\"\n                            VerticalAlignment=\"Center\"\n                            DockPanel.Dock=\"Left\">\n                                <TextBlock Text=\"{x:Static resx:ResUI.TbEnableTunAs}\" />\n                                <ToggleButton\n                                x:Name=\"togEnableTun\"\n                                Margin=\"4\"\n                                Click=\"togEnableTun_Click\"\n                                HorizontalAlignment=\"Left\" ToolTip=\"Open as Admin\" />\n                            </StackPanel>\n\n                            <StackPanel\n                            Margin=\"8,0\"\n                            VerticalAlignment=\"Center\"\n                            DockPanel.Dock=\"Left\"\n                            Orientation=\"Horizontal\">\n                                <ComboBox\n                                x:Name=\"cmbSystemProxy\"\n                                Visibility=\"Collapsed\"\n                                Width=\"120\"\n                                Margin=\"8,0\"\n                                materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.menuSystemproxy}\"\n                                FontSize=\"{DynamicResource StdFontSize}\"\n                                Style=\"{StaticResource MaterialDesignFloatingHintComboBox}\">\n                                    <ComboBoxItem Content=\"{x:Static resx:ResUI.menuSystemProxyClear}\" />\n                                    <ComboBoxItem Content=\"{x:Static resx:ResUI.menuSystemProxySet}\" />\n                                    <ComboBoxItem Content=\"{x:Static resx:ResUI.menuSystemProxyNothing}\" />\n                                    <ComboBoxItem Content=\"{x:Static resx:ResUI.menuSystemProxyPac}\" />\n                                </ComboBox>\n\n\n                            </StackPanel>\n\n                            <StackPanel Margin=\"8,0\" VerticalAlignment=\"Center\">\n                                <TextBlock\n                                x:Name=\"txtRunningServerDisplay\"\n                                PreviewMouseDown=\"txtRunningInfoDisplay_MouseDoubleClick\"\n                                Style=\"{StaticResource StatusbarItem}\" />\n                                <Border Margin=\"2\" />\n                                <TextBlock\n                                x:Name=\"txtRunningInfoDisplay\"\n                                PreviewMouseDown=\"txtRunningInfoDisplay_MouseDoubleClick\"\n                                Style=\"{StaticResource StatusbarItem}\" />\n                            </StackPanel>\n                        </DockPanel>\n                    </materialDesign:ColorZone>\n\n                    <Grid x:Name=\"gridMain\">\n                        <Grid.RowDefinitions>\n                            <RowDefinition Height=\"1*\" />\n                            <RowDefinition Height=\"10\" />\n                            <RowDefinition Height=\"1*\" />\n                        </Grid.RowDefinitions>\n                        <DataGrid\n                        x:Name=\"lstProfiles\"\n                        Grid.Row=\"0\"\n                        materialDesign:DataGridAssist.CellPadding=\"2,2\"\n                        AutoGenerateColumns=\"False\"\n                        BorderThickness=\"1\"\n                        CanUserAddRows=\"False\"\n                        CanUserResizeRows=\"False\"\n                        CanUserSortColumns=\"False\"\n                        EnableRowVirtualization=\"True\"\n                        Focusable=\"True\"\n                        GridLinesVisibility=\"All\"\n                        HeadersVisibility=\"All\"\n                        IsReadOnly=\"True\"\n                        RowHeaderWidth=\"40\"\n                        Style=\"{StaticResource DefDataGrid}\">\n                            <DataGrid.InputBindings>\n                                <KeyBinding Command=\"ApplicationCommands.NotACommand\" Gesture=\"Ctrl+C\" />\n                                <KeyBinding Command=\"ApplicationCommands.NotACommand\" Gesture=\"Ctrl+V\" />\n                                <KeyBinding Command=\"ApplicationCommands.NotACommand\" Gesture=\"Delete\" />\n                                <KeyBinding Command=\"ApplicationCommands.NotACommand\" Gesture=\"Enter\" />\n                            </DataGrid.InputBindings>\n                            <DataGrid.ContextMenu>\n                                <ContextMenu Style=\"{StaticResource DefContextMenu}\">\n                                    <MenuItem\n                                    x:Name=\"menuEditServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuEditServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuSetDefaultServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuSetDefaultServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuRemoveServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRemoveServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuRemoveDuplicateServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRemoveDuplicateServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuCopyServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuCopyServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuShareServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuShareServer}\" />\n                                    <Separator />\n                                    <MenuItem\n                                    x:Name=\"menuMixedTestServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuMixedTestServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuPingServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuPingServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuTcpingServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuTcpingServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuRealPingServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRealPingServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuSpeedServer\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuSpeedServer}\" />\n                                    <MenuItem\n                                    x:Name=\"menuSortServerResult\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuSortServerResult}\" />\n                                    <Separator />\n                                    <MenuItem\n                                    x:Name=\"menuMoveToGroup\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuMoveToGroup}\">\n                                        <MenuItem Height=\"Auto\">\n                                            <MenuItem.Header>\n                                                <DockPanel>\n                                                    <ComboBox\n                                                    x:Name=\"cmbMoveToGroup\"\n                                                    Width=\"200\"\n                                                    materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.menuSubscription}\"\n                                                    DisplayMemberPath=\"remarks\"\n                                                    FontSize=\"{DynamicResource StdFontSize}\"\n                                                    Style=\"{StaticResource MaterialDesignFilledComboBox}\" />\n                                                </DockPanel>\n                                            </MenuItem.Header>\n                                        </MenuItem>\n                                    </MenuItem>\n                                    <MenuItem Header=\"{x:Static resx:ResUI.menuMoveTo}\">\n                                        <MenuItem\n                                        x:Name=\"menuMoveTop\"\n                                        Height=\"{StaticResource MenuItemHeight}\"\n                                        Header=\"{x:Static resx:ResUI.menuMoveTop}\" />\n                                        <MenuItem\n                                        x:Name=\"menuMoveUp\"\n                                        Height=\"{StaticResource MenuItemHeight}\"\n                                        Header=\"{x:Static resx:ResUI.menuMoveUp}\" />\n                                        <MenuItem\n                                        x:Name=\"menuMoveDown\"\n                                        Height=\"{StaticResource MenuItemHeight}\"\n                                        Header=\"{x:Static resx:ResUI.menuMoveDown}\" />\n                                        <MenuItem\n                                        x:Name=\"menuMoveBottom\"\n                                        Height=\"{StaticResource MenuItemHeight}\"\n                                        Header=\"{x:Static resx:ResUI.menuMoveBottom}\" />\n                                    </MenuItem>\n                                    <MenuItem\n                                    x:Name=\"menuSelectAll\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Click=\"menuSelectAll_Click\"\n                                    Header=\"{x:Static resx:ResUI.menuSelectAll}\" />\n                                    <Separator />\n                                    <MenuItem\n                                    x:Name=\"menuExport2ClientConfig\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuExport2ClientConfig}\" />\n                                    <MenuItem\n                                    x:Name=\"menuExport2ShareUrl\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuExport2ShareUrl}\" />\n                                    <MenuItem\n                                    x:Name=\"menuExport2SubContent\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuExport2SubContent}\" />\n                                </ContextMenu>\n                            </DataGrid.ContextMenu>\n                            <DataGrid.Resources>\n                                <Style BasedOn=\"{StaticResource MaterialDesignDataGridRow}\" TargetType=\"DataGridRow\">\n                                    <EventSetter Event=\"MouseDoubleClick\" Handler=\"LstProfiles_MouseDoubleClick\" />\n                                    <Style.Triggers>\n                                        <DataTrigger Binding=\"{Binding configType}\" Value=\"ERROR\">\n                                            <Setter Property=\"Background\" Value=\"Red\"></Setter>\n                                        </DataTrigger>\n                                        <DataTrigger Binding=\"{Binding configType}\" Value=\"Usage\">\n                                            <Setter Property=\"Background\" Value=\"#FFFDDEDE\"></Setter>\n                                            <Setter Property=\"BorderThickness\" Value=\"1\"></Setter>\n                                            <Setter Property=\"BorderBrush\" Value=\"Black\"></Setter>\n                                            <Setter Property=\"IsSelected\" Value=\"False\"></Setter>\n                                            <Setter Property=\"IsEnabled\" Value=\"True\"></Setter>\n                                        </DataTrigger>\n                                        <MultiDataTrigger>\n                                            <MultiDataTrigger.Conditions>\n                                                <Condition Binding=\"{Binding configType}\" Value=\"Usage\" />\n                                                <Condition Binding=\"{Binding ElementName=togDarkMode, Path=IsChecked}\" Value=\"True\" />\n                                            </MultiDataTrigger.Conditions>\n                                            <Setter Property=\"Background\" Value=\"#FF484343\"></Setter>\n                                        </MultiDataTrigger>\n                                    </Style.Triggers>\n                                </Style>\n\n                                <Style BasedOn=\"{StaticResource MaterialDesignDataGridColumnHeader}\" TargetType=\"DataGridColumnHeader\">\n                                    <EventSetter Event=\"Click\" Handler=\"LstProfiles_ColumnHeader_Click\" />\n                                </Style>\n\n                                <Style BasedOn=\"{StaticResource MaterialDesignDataGridCell}\" TargetType=\"DataGridCell\">\n                                    <Style.Triggers>\n                                        <DataTrigger Binding=\"{Binding isActive}\" Value=\"True\">\n                                            <Setter Property=\"Background\" Value=\"{DynamicResource PrimaryHueLightBrush}\" />\n                                            <Setter Property=\"Foreground\" Value=\"Black\" />\n                                            <Setter Property=\"BorderBrush\" Value=\"{DynamicResource PrimaryHueLightBrush}\" />\n                                        </DataTrigger>\n                                    </Style.Triggers>\n                                </Style>\n                            </DataGrid.Resources>\n                            <DataGrid.Columns>\n\n                                <base:MyDGTextColumn\n                                Width=\"80\"\n                                Binding=\"{Binding configType}\"\n                                ExName=\"configType\"\n                                Header=\"{x:Static resx:ResUI.LvServiceType}\" />\n                                <base:MyDGTextColumn\n                                Width=\"150\"\n                                Binding=\"{Binding remarks}\"\n                                ExName=\"remarks\"\n                                Header=\"{x:Static resx:ResUI.LvRemarks}\" />\n                                <base:MyDGTextColumn\n                                Width=\"120\"\n                                Binding=\"{Binding address}\"\n                                ExName=\"address\"\n                                Header=\"{x:Static resx:ResUI.LvAddress}\" />\n\n                                <base:MyDGTextColumn\n                                Width=\"100\"\n                                Binding=\"{Binding delayVal}\"\n                                ExName=\"delayVal\"\n                                Header=\"{x:Static resx:ResUI.LvTestDelay}\">\n                                    <DataGridTextColumn.ElementStyle>\n                                        <Style TargetType=\"{x:Type TextBlock}\">\n                                            <Setter Property=\"HorizontalAlignment\" Value=\"Right\" />\n                                            <Setter Property=\"Foreground\" Value=\"{Binding delay, Converter={StaticResource DelayColorConverter}}\" />\n                                        </Style>\n                                    </DataGridTextColumn.ElementStyle>\n                                </base:MyDGTextColumn>\n                                <base:MyDGTextColumn\n                                Width=\"100\"\n                                Binding=\"{Binding speedVal}\"\n                                ExName=\"speedVal\"\n                                Header=\"{x:Static resx:ResUI.LvTestSpeed}\">\n                                    <DataGridTextColumn.ElementStyle>\n                                        <Style TargetType=\"{x:Type TextBlock}\">\n                                            <Setter Property=\"HorizontalAlignment\" Value=\"Right\" />\n                                        </Style>\n                                    </DataGridTextColumn.ElementStyle>\n                                </base:MyDGTextColumn>\n                                <base:MyDGTextColumn\n                                Width=\"60\"\n                                Binding=\"{Binding port}\"\n                                ExName=\"port\"\n                                Header=\"{x:Static resx:ResUI.LvPort}\" />\n\n                                <base:MyDGTextColumn\n                                x:Name=\"colTodayUp\"\n                                Width=\"100\"\n                                Binding=\"{Binding todayUp}\"\n                                ExName=\"todayUp\"\n                                Header=\"{x:Static resx:ResUI.LvTodayUploadDataAmount}\" />\n                                <base:MyDGTextColumn\n                                x:Name=\"colTodayDown\"\n                                Width=\"100\"\n                                Binding=\"{Binding todayDown}\"\n                                ExName=\"todayDown\"\n                                Header=\"{x:Static resx:ResUI.LvTodayDownloadDataAmount}\" />\n                                <base:MyDGTextColumn\n                                x:Name=\"colTotalUp\"\n                                Width=\"100\"\n                                Binding=\"{Binding totalUp}\"\n                                ExName=\"totalUp\"\n                                Header=\"{x:Static resx:ResUI.LvTotalUploadDataAmount}\" />\n                                <base:MyDGTextColumn\n                                x:Name=\"colTotalDown\"\n                                Width=\"100\"\n                                Binding=\"{Binding totalDown}\"\n                                ExName=\"totalDown\"\n                                Header=\"{x:Static resx:ResUI.LvTotalDownloadDataAmount}\" />\n                                <base:MyDGTextColumn\n                                Width=\"100\"\n                                Binding=\"{Binding security}\"\n                                ExName=\"security\"\n                                Header=\"{x:Static resx:ResUI.LvEncryptionMethod}\" />\n                                <base:MyDGTextColumn\n                                Width=\"100\"\n                                Binding=\"{Binding network}\"\n                                ExName=\"network\"\n                                Header=\"{x:Static resx:ResUI.LvTransportProtocol}\" />\n                                <base:MyDGTextColumn\n                                Width=\"100\"\n                                Binding=\"{Binding streamSecurity}\"\n                                ExName=\"streamSecurity\"\n                                Header=\"{x:Static resx:ResUI.LvTLS}\" />\n                                <base:MyDGTextColumn\n                                Width=\"100\"\n                                Binding=\"{Binding subRemarks}\"\n                                ExName=\"subRemarks\"\n                                Header=\"{x:Static resx:ResUI.LvSubscription}\" />\n                            </DataGrid.Columns>\n                        </DataGrid>\n                        <GridSplitter Grid.Row=\"1\" HorizontalAlignment=\"Stretch\" />\n                        <local:MsgView Grid.Row=\"2\" />\n                    </Grid>\n                </DockPanel>\n                <tb:TaskbarIcon\n                x:Name=\"tbNotify\"\n                IconSource=\"/v2rayN.ico\"\n                NoLeftClickDelay=\"True\">\n                    <tb:TaskbarIcon.ContextMenu>\n                        \n                        <ContextMenu Style=\"{StaticResource DefContextMenu}\">\n                            <MenuItem Height=\"500\">\n                                <MenuItem.Header>\n                                    <local:HiddifyUI DataContext=\"{Binding}\" Height=\"500\"  x:Name=\"HiddifyUI2\"   HorizontalAlignment=\"Stretch\" Width=\"424\" ShowTitleBar=\"False\"/>\n                                </MenuItem.Header>\n                            </MenuItem>\n                            <MenuItem x:Name=\"menuSystemConnect\" Height=\"128\" Visibility=\"Collapsed\">\n                                <MenuItem.Header>\n\n                                    <StackPanel Orientation=\"Horizontal\" Grid.Row=\"1\" HorizontalAlignment=\"Center\" VerticalAlignment=\"Center\" >\n                                        <Button x:Name=\"ConnectVPN\" Width=\"96\" Height=\"96\" materialDesign:ButtonProgressAssist.IsIndeterminate=\"{Binding ConnectProgress}\"\n                                            materialDesign:ButtonProgressAssist.IsIndicatorVisible=\"{Binding ConnectProgress}\"\n                                            Background=\"{Binding ConnectColor}\"\n\n                                                Command=\"{Binding HomeConnectCmd}\"\n                Style=\"{StaticResource MaterialDesignFloatingActionButton}\" \n                Foreground=\"{DynamicResource SecondaryHueMidBrushForeground}\" BorderBrush=\"{x:Null}\">\n\n                                            <Image Source=\"/v2rayN.ico\" Width=\"36\" Height=\"36\" />\n\n                                        </Button>\n                                        <Label Name=\"connectlbl\" Foreground=\"{Binding ConnectVPNLabelColor}\" \n                                               HorizontalAlignment=\"Center\" \n                                               VerticalAlignment=\"Center\" Grid.Row=\"1\"               \n                Height=\"auto\" Width=\"auto\" FontSize=\"18\" Content=\"{Binding ConnectVPNLabel}\" >\n\n                                        </Label>\n                                    </StackPanel>\n                                </MenuItem.Header>\n                            </MenuItem>\n\n                            <Separator x:Name=\"sepRoutings\" Visibility=\"Collapsed\" />\n                            <MenuItem x:Name=\"menuRoutings\" Height=\"Auto\" Visibility=\"Collapsed\">\n                                <MenuItem.Header>\n                                    <DockPanel >\n                                        <ComboBox\n                                        x:Name=\"cmbRoutings\"\n                                        MaxWidth=\"300\"\n                                        materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.menuRouting}\"\n                                        DisplayMemberPath=\"remarks\"\n                                        FontSize=\"{DynamicResource StdFontSize}\"\n                                        Style=\"{StaticResource MaterialDesignFilledComboBox}\" />\n                                    </DockPanel>\n                                </MenuItem.Header>\n                            </MenuItem>\n                            <MenuItem Height=\"Auto\" Visibility=\"Collapsed\">\n                                <MenuItem.Header>\n                                    <DockPanel>\n                                        <ComboBox\n                                        x:Name=\"cmbServers\"\n                                        MaxWidth=\"300\"\n                                        materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.menuServers}\"\n                                        DisplayMemberPath=\"Text\"\n                                        FontSize=\"{DynamicResource StdFontSize}\"\n                                        Style=\"{StaticResource MaterialDesignFilledComboBox}\" />\n                                    </DockPanel>\n                                </MenuItem.Header>\n                            </MenuItem>\n                            <Separator Visibility=\"Collapsed\" />\n                            <MenuItem Visibility=\"Collapsed\"\n                            x:Name=\"menuAddServerViaClipboard2\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Header=\"{x:Static resx:ResUI.menuAddServerViaClipboard}\" />\n                            <MenuItem Visibility=\"Collapsed\"\n                            x:Name=\"menuAddServerViaScan2\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Header=\"{x:Static resx:ResUI.menuAddServerViaScan}\" />\n                            <MenuItem\n                            x:Name=\"menuSubUpdate2\" Visibility=\"Collapsed\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Header=\"{x:Static resx:ResUI.menuSubUpdate}\" />\n                            <MenuItem\n                            x:Name=\"menuSubUpdateViaProxy2\" Visibility=\"Collapsed\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Header=\"{x:Static resx:ResUI.menuSubUpdateViaProxy}\" />\n                            <Separator />\n                            <MenuItem\n                            x:Name=\"menuExit\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Click=\"menuExit_Click\"\n                            Header=\"{x:Static resx:ResUI.menuExit}\" />\n                        </ContextMenu>\n                    </tb:TaskbarIcon.ContextMenu>\n                    <tb:TaskbarIcon.TrayToolTip>\n                        <Border\n                        x:Name=\"borTrayToolTip\"\n                        Width=\"Auto\"\n                        Height=\"Auto\"\n                        Background=\"{DynamicResource MaterialDesignLightBackground}\"\n                        BorderBrush=\"{DynamicResource MaterialDesignDarkBackground}\"\n                        BorderThickness=\"0\"\n                        CornerRadius=\"4\">\n                            <TextBlock\n                            Margin=\"8\"\n                            HorizontalAlignment=\"Center\"\n                            VerticalAlignment=\"Center\"\n                            Foreground=\"{DynamicResource MaterialDesignDarkBackground}\"\n                            Text=\"{Binding Mode=OneWay, Path=ToolTipText}\" />\n                        </Border>\n                    </tb:TaskbarIcon.TrayToolTip>\n                </tb:TaskbarIcon>\n                <materialDesign:Snackbar x:Name=\"MainSnackbar\" MessageQueue=\"{materialDesign:MessageQueue}\" />\n            </Grid>\n        </Grid>\n    </materialDesign:DialogHost>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/MainWindow.xaml.cs",
    "content": "﻿using DynamicData;\nusing DynamicData.Binding;\nusing ReactiveUI;\nusing Splat;\nusing System.ComponentModel;\nusing System.IO;\nusing System.IO.Pipes;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Controls.Primitives;\nusing System.Windows.Input;\nusing System.Windows.Interop;\nusing System.Windows.Media;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.Resx;\nusing v2rayN.Tool;\nusing v2rayN.ViewModels;\nusing Point = System.Windows.Point;\n\nnamespace v2rayN.Views\n{\n    public partial class MainWindow\n    {\n        private NamedPipeServerStream _pipeServer;\n\n        private static Config _config;\n        private void HandleClientConnection(IAsyncResult ar)\n        {\n            using (var reader = new StreamReader(_pipeServer))\n            {\n                string message = reader.ReadLine()??\"\";\n                \n                HandleDeepLink(message);\n             \n            }\n\n            // Disconnect the client and start listening for another connection\n            try { \n            _pipeServer.Disconnect();\n                _pipeServer.Dispose();\n            }\n            catch (Exception e){ }\n            _pipeServer = new NamedPipeServerStream(\"HiddifyPipe\");\n            _pipeServer.BeginWaitForConnection(HandleClientConnection, null);\n        }\n        public MainWindow()\n        {\n            _pipeServer = new NamedPipeServerStream(\"HiddifyPipe\");\n            _pipeServer.BeginWaitForConnection(HandleClientConnection, PipeDirection.InOut);\n\n            InitializeComponent();\n            _config = LazyConfig.Instance.GetConfig();\n\n            App.Current.SessionEnding += Current_SessionEnding;\n            this.Closing += MainWindow_Closing;\n            this.PreviewKeyDown += MainWindow_PreviewKeyDown;\n            btnAutofitColumnWidth.Click += BtnAutofitColumnWidth_Click;\n            txtServerFilter.PreviewKeyDown += TxtServerFilter_PreviewKeyDown;\n            lstProfiles.PreviewKeyDown += LstProfiles_PreviewKeyDown;\n            lstProfiles.SelectionChanged += lstProfiles_SelectionChanged;\n            lstProfiles.LoadingRow += LstProfiles_LoadingRow;\n            if (_config.uiItem.enableDragDropSort)\n            {\n                lstProfiles.AllowDrop = true;\n                lstProfiles.PreviewMouseLeftButtonDown += LstProfiles_PreviewMouseLeftButtonDown;\n                lstProfiles.MouseMove += LstProfiles_MouseMove;\n                lstProfiles.DragEnter += LstProfiles_DragEnter;\n                lstProfiles.Drop += LstProfiles_Drop;\n            }\n\n            ViewModel = new MainWindowViewModel(MainSnackbar.MessageQueue!, UpdateViewHandler);\n            if (ViewModel.CurrentLanguage == \"fa-Ir\")\n                FlowDirection = FlowDirection.RightToLeft;\n            DataContext = ViewModel;\n\n            // Handle URI scheme(Deep link), If there is any\n            HandleDeepLink();\n\n            if (App.IsNewInstance)\n            {\n                App.Current.Shutdown();\n                Environment.Exit(0);\n                return;\n            }\n\n\n            // Declare and start a thread to handle reloading main page whenever need\n            new Thread(delegate ()\n            {\n                HandlePageReloading();\n            }).Start();\n\n            Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));\n\n            for (int i = Global.MinFontSize; i <= Global.MinFontSize + 8; i++)\n            {\n                //cmbCurrentFontSize.Items.Add(i.ToString());\n            }\n\n            Global.Languages.ForEach(it =>\n            {\n                //cmbCurrentLanguage.Items.Add(it);\n            });\n\n            this.WhenActivated(disposables =>\n            {\n                //home\n                this.OneWayBind(ViewModel, vm => vm.ProfileItems, v => v.lstProfiles.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedProfile, v => v.lstProfiles.SelectedItem).DisposeWith(disposables);\n\n                this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.lstGroup.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSub, v => v.lstGroup.SelectedItem).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddSubCmd, v => v.btnAddSub).DisposeWith(disposables);\n\n                //servers\n                this.BindCommand(ViewModel, vm => vm.AddVmessServerCmd, v => v.menuAddVmessServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddVlessServerCmd, v => v.menuAddVlessServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddShadowsocksServerCmd, v => v.menuAddShadowsocksServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddSocksServerCmd, v => v.menuAddSocksServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddTrojanServerCmd, v => v.menuAddTrojanServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddCustomServerCmd, v => v.menuAddCustomServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan).DisposeWith(disposables);\n\n                //servers delete\n                this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.menuEditServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RemoveServerCmd, v => v.menuRemoveServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RemoveDuplicateServerCmd, v => v.menuRemoveDuplicateServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CopyServerCmd, v => v.menuCopyServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SetDefaultServerCmd, v => v.menuSetDefaultServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ShareServerCmd, v => v.menuShareServer).DisposeWith(disposables);\n\n                //servers move\n                this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.cmbMoveToGroup.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedMoveToGroup, v => v.cmbMoveToGroup.SelectedItem).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.MoveTopCmd, v => v.menuMoveTop).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.MoveUpCmd, v => v.menuMoveUp).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.MoveDownCmd, v => v.menuMoveDown).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.MoveBottomCmd, v => v.menuMoveBottom).DisposeWith(disposables);\n\n                //servers ping\n                this.BindCommand(ViewModel, vm => vm.MixedTestServerCmd, v => v.menuMixedTestServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.PingServerCmd, v => v.menuPingServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.TcpingServerCmd, v => v.menuTcpingServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RealPingServerCmd, v => v.menuRealPingServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SpeedServerCmd, v => v.menuSpeedServer).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SortServerResultCmd, v => v.menuSortServerResult).DisposeWith(disposables);\n\n                //servers export\n                this.BindCommand(ViewModel, vm => vm.Export2ClientConfigCmd, v => v.menuExport2ClientConfig).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.Export2ShareUrlCmd, v => v.menuExport2ShareUrl).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.Export2SubContentCmd, v => v.menuExport2SubContent).DisposeWith(disposables);\n\n                //sub\n                this.BindCommand(ViewModel, vm => vm.SubSettingCmd, v => v.menuSubSetting).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SubGroupUpdateCmd, v => v.menuSubGroupUpdate).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SubGroupUpdateViaProxyCmd, v => v.menuSubGroupUpdateViaProxy).DisposeWith(disposables);\n\n                //setting\n                this.BindCommand(ViewModel, vm => vm.OptionSettingCmd, v => v.menuOptionSetting).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RoutingSettingCmd, v => v.menuRoutingSetting).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.DNSSettingCmd, v => v.menuDNSSetting).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.GlobalHotkeySettingCmd, v => v.menuGlobalHotkeySetting).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RebootAsAdminCmd, v => v.menuRebootAsAdmin).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ClearServerStatisticsCmd, v => v.menuClearServerStatistics).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ImportOldGuiConfigCmd, v => v.menuImportOldGuiConfig).DisposeWith(disposables);\n\n                //checkupdate\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateNCmd, v => v.menuCheckUpdateN).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateV2flyCoreCmd, v => v.menuCheckUpdateV2flyCore).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateSagerNetCoreCmd, v => v.menuCheckUpdateSagerNetCore).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateXrayCoreCmd, v => v.menuCheckUpdateXrayCore).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateClashCoreCmd, v => v.menuCheckUpdateClashCore).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateClashMetaCoreCmd, v => v.menuCheckUpdateClashMetaCore).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateSingBoxCoreCmd, v => v.menuCheckUpdateSingBoxCore).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.CheckUpdateGeoCmd, v => v.menuCheckUpdateGeo).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.ReloadCmd, v => v.menuReload).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.BlReloadEnabled, v => v.menuReload.IsEnabled).DisposeWith(disposables);\n\n                //system proxy\n                //this.OneWayBind(ViewModel, vm => vm.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);\n                //this.OneWayBind(ViewModel, vm => vm.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);\n                //this.OneWayBind(ViewModel, vm => vm.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);\n                //this.OneWayBind(ViewModel, vm => vm.BlSystemProxyPac, v => v.menuSystemProxyPac2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SystemProxyClearCmd, v => v.menuSystemProxyClear).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SystemProxyPacCmd, v => v.menuSystemProxyPac).DisposeWith(disposables);\n                //this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables);\n\n                //routings and servers\n                this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings.SelectedItem).DisposeWith(disposables);\n                //this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.menuRoutings.Visibility).DisposeWith(disposables);\n                //this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.sepRoutings.Visibility).DisposeWith(disposables);\n\n                this.OneWayBind(ViewModel, vm => vm.Servers, v => v.cmbServers.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedServer, v => v.cmbServers.SelectedItem).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.BlServers, v => v.cmbServers.Visibility).DisposeWith(disposables);\n\n                //tray menu\n                this.BindCommand(ViewModel, vm => vm.AddServerViaClipboardCmd, v => v.menuAddServerViaClipboard2).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.AddServerViaScanCmd, v => v.menuAddServerViaScan2).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SubUpdateCmd, v => v.menuSubUpdate2).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SubUpdateViaProxyCmd, v => v.menuSubUpdateViaProxy2).DisposeWith(disposables);\n\n                this.OneWayBind(ViewModel, vm => vm.NotifyIcon, v => v.tbNotify.Icon).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.RunningServerToolTipText, v => v.tbNotify.ToolTipText).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.NotifyLeftClickCmd, v => v.tbNotify.LeftClickCommand).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.AppIcon, v => v.Icon).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.BlShowTrayTip, v => v.borTrayToolTip.Visibility).DisposeWith(disposables);\n\n                //status bar\n                this.OneWayBind(ViewModel, vm => vm.InboundDisplay, v => v.txtInboundDisplay.Text).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.InboundLanDisplay, v => v.txtInboundLanDisplay.Text).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.RunningServerDisplay, v => v.txtRunningServerDisplay.Text).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.RunningInfoDisplay, v => v.txtRunningInfoDisplay.Text).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.SpeedProxyDisplay, v => v.txtSpeedProxyDisplay.Text).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.SpeedDirectDisplay, v => v.txtSpeedDirectDisplay.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.EnableTun, v => v.togEnableTun.IsChecked).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.SystemProxySelected, v => v.cmbSystemProxy.SelectedIndex).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.cmbRoutings2.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedRouting, v => v.cmbRoutings2.SelectedItem).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.BlRouting, v => v.cmbRoutings2.Visibility).DisposeWith(disposables);\n\n                //UI\n                //this.Bind(ViewModel, vm => vm.ColorModeDark, v => v.togDarkMode.IsChecked).DisposeWith(disposables);\n                //this.OneWayBind(ViewModel, vm => vm.Swatches, v => v.cmbSwatches.ItemsSource).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.Text).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.Text).DisposeWith(disposables);\n            });\n\n            RestoreUI();\n            AddHelpMenuItem();\n\n            var IsAdministrator = Utils.IsAdministrator();\n            this.Title = $\"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}\";\n\n            //spEnableTun.IsEnabled = IsAdministrator ? Visibility.Visible : Visibility.Collapsed;\n\n            //if (_config.uiItem.autoHideStartup)\n            //{\n            //    WindowState = WindowState.Minimized;\n            //}\n\n            if (!_config.guiItem.enableHWA)\n            {\n                RenderOptions.ProcessRenderMode = RenderMode.SoftwareOnly;\n            }\n            App.Current.MainWindow.Show();\n            Application.Current.MainWindow.Show();\n            if (Application.Current.MainWindow.WindowState == WindowState.Minimized)\n            {\n                Application.Current.MainWindow.WindowState = WindowState.Normal;\n            }\n            Application.Current.MainWindow.Activate();\n\n            \n        }\n\n        private void HandlePageReloading()\n        {\n            while (true)\n            {\n                if (Utils.DoesMainPageNeedReload())\n                {\n                    this.Dispatcher.Invoke(() =>\n                    {\n                        ViewModel?.InitSubscriptionView();\n                        ViewModel?.SubSelectedChanged(true);\n                        if (this.IsVisible)\n                        {\n                            this.Show();\n                        }\n                        if (this.WindowState == WindowState.Minimized)\n                        {\n                            this.WindowState = WindowState.Normal;\n                        }\n                        this.Activate();\n                        this.Topmost = true;\n                        this.Topmost = false;\n                        this.Focus();\n                        Utils.UnsetMainPageReload();\n\n                    });\n                }\n                Thread.Sleep(666);\n            }\n        }\n\n        public void HandleDeepLink(String? message=null)\n        {\n            if (message != null)\n                this.Dispatcher.Invoke(Activate);\n            \n            string[] Args = Environment.GetCommandLineArgs();\n            if (Args.Length > 1|| message!=null)\n            {\n                \n                var uri = message??Args[1];\n                var (isValidUri, scheme) = DeepLinking.IsUriForProgram(uri);\n                \n                if (isValidUri)\n                {\n                    \n\n                    this.Dispatcher.Invoke(() =>\n                    {\n                        // Parse uri\n                        var item = DeepLinking.ParseUri(uri);\n\n\n                        // Error handling\n                        if (item.err != null && item.err != \"\" && item.res == null)\n                        {\n                            // Notice error\n                            ViewModel?._noticeHandler?.SendMessage(ResUI.MsgDeepLinkIsInvalid);\n\n                        }\n                        // Add server or subscription to the program\n                        else\n                        {\n                            if (item.res.protocol != null)\n                            {\n                                ViewModel?.AddServerOrSubViaDeepLink(item.res.protocol.Uri);\n\n                                Utils.SetMainPageReload();\n                            }\n                            else if (item.res.subscription != null)\n                            {\n                                ViewModel?.AddServerOrSubViaDeepLink(item.res.subscription.Url);\n                                Utils.SetMainPageReload();\n                            }\n                            else\n                            {\n                                // WTF is happening here !\n                            }\n                        }\n                    });\n                }\n            }\n        }\n        #region Event \n\n        private void UpdateViewHandler(EViewAction action)\n        {\n            if (action == EViewAction.AdjustMainLvColWidth)\n            {\n                Application.Current.Dispatcher.Invoke(() =>\n                {\n                    AutofitColumnWidth();\n                });\n            }\n            else if (action == EViewAction.ProfilesFocus)\n            {\n                lstProfiles.Focus();\n            }\n        }\n\n        private void MainWindow_Closing(object? sender, CancelEventArgs e)\n        {\n            e.Cancel = true;\n            ViewModel?.ShowHideWindow(false);\n\n        }\n\n\n        private void update_sub_click(object sender, RoutedEventArgs e)\n        {\n            var item = (MenuItem)sender;\n\n            //MessageBox.Show(item.Uid);           \n            ViewModel?.UpdateSubscriptionProcess(item.Uid, false);//without proxy\n            ViewModel?.UpdateSubscriptionProcess(item.Uid, true);//with proxy\n            \n\n        }\n\n        private void menuExit_Click(object sender, RoutedEventArgs e)\n        {\n            tbNotify.Dispose();\n            StorageUI();\n            ViewModel?.MyAppExit(false);\n            if (_pipeServer != null)\n            {\n                _pipeServer.Dispose();\n                _pipeServer = null;\n            }\n        }\n\n        private void Current_SessionEnding(object sender, SessionEndingCancelEventArgs e)\n        {\n            Utils.SaveLog(\"Current_SessionEnding\");\n            StorageUI();\n            ViewModel?.MyAppExit(true);\n        }\n\n        private void lstProfiles_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)\n        {\n            ViewModel.SelectedProfiles = lstProfiles.SelectedItems.Cast<ProfileItemModel>().ToList();\n        }\n\n        private void LstProfiles_LoadingRow(object? sender, DataGridRowEventArgs e)\n        {\n            e.Row.Header = $\" {e.Row.GetIndex() + 1}\";\n            \n        }\n\n        private void LstProfiles_MouseDoubleClick(object sender, MouseButtonEventArgs e)\n        {\n            if (ViewModel?.SelectedProfile?.configType == EConfigType.Usage)\n            {\n                Utils.ProcessStart($\"{ViewModel?.SelectedProfile?.address}\");\n                return;\n            }\n\n                \n            //if (_config.uiItem.doubleClick2Activate)\n            if (ViewModel?.SelectedProfile?.isActive==false)\n            {\n                ViewModel?.SetDefaultServer();\n            }\n            else\n            {\n                if (((int)ViewModel?.SelectedProfile?.configType) >100 ) return;\n                ViewModel?.EditServer(false, EConfigType.Custom);\n            }\n            ViewModel?.ServerSpeedtest(ESpeedActionType.Realping);\n        }\n\n        private void LstProfiles_ColumnHeader_Click(object sender, RoutedEventArgs e)\n        {\n            var colHeader = sender as DataGridColumnHeader;\n            if (colHeader == null || colHeader.TabIndex < 0 || colHeader.Column == null)\n            {\n                return;\n            }\n\n            var colName = ((MyDGTextColumn)colHeader.Column).ExName;\n            ViewModel?.SortServer(colName);\n        }\n\n        private void menuSelectAll_Click(object sender, RoutedEventArgs e)\n        {\n            lstProfiles.SelectAll();\n        }\n\n        private void MainWindow_PreviewKeyDown(object sender, KeyEventArgs e)\n        {\n            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))\n            {\n                if (e.Key == Key.V)\n                {\n                    ViewModel?.AddServerOrSubViaClipboard();\n                }\n                else if (e.Key == Key.P)\n                {\n                    ViewModel?.ServerSpeedtest(ESpeedActionType.Ping);\n                }\n                else if (e.Key == Key.O)\n                {\n                    ViewModel?.ServerSpeedtest(ESpeedActionType.Tcping);\n                }\n                else if (e.Key == Key.R)\n                {\n                    ViewModel?.ServerSpeedtest(ESpeedActionType.Realping);\n                }\n                else if (e.Key == Key.S)\n                {\n                    _ = ViewModel?.ScanScreenTaskAsync();\n                }\n                else if (e.Key == Key.T)\n                {\n                    ViewModel?.ServerSpeedtest(ESpeedActionType.Speedtest);\n                }\n                else if (e.Key == Key.E)\n                {\n                    ViewModel?.ServerSpeedtest(ESpeedActionType.Mixedtest);\n                }\n            }\n            else\n            {\n                if (e.Key == Key.F5)\n                {\n                    ViewModel?.Reload();\n                }\n            }\n        }\n\n        private void LstProfiles_PreviewKeyDown(object sender, KeyEventArgs e)\n        {\n            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))\n            {\n                if (e.Key == Key.A)\n                {\n                    menuSelectAll_Click(null, null);\n                }\n                else if (e.Key == Key.C)\n                {\n                    ViewModel?.Export2ShareUrl();\n                }\n                else if (e.Key == Key.D)\n                {\n                    ViewModel?.EditServer(false, EConfigType.Custom);\n                }\n                else if (e.Key == Key.F)\n                {\n                    ViewModel?.ShareServer();\n                }\n            }\n            else\n            {\n                if (e.Key is Key.Enter or Key.Return)\n                {\n                    ViewModel?.SetDefaultServer();\n                }\n                else if (e.Key == Key.Delete)\n                {\n                    ViewModel?.RemoveServer();\n                }\n                else if (e.Key == Key.T)\n                {\n                    ViewModel?.MoveServer(EMove.Top);\n                }\n                else if (e.Key == Key.U)\n                {\n                    ViewModel?.MoveServer(EMove.Up);\n                }\n                else if (e.Key == Key.D)\n                {\n                    ViewModel?.MoveServer(EMove.Down);\n                }\n                else if (e.Key == Key.B)\n                {\n                    ViewModel?.MoveServer(EMove.Bottom);\n                }\n            }\n        }\n\n        private void menuClose_Click(object sender, RoutedEventArgs e)\n        {\n            StorageUI();\n            ViewModel?.ShowHideWindow(false);\n        }\n\n        private void menuPromotion_Click(object sender, RoutedEventArgs e)\n        {\n            Utils.ProcessStart($\"{Utils.Base64Decode(Global.PromotionUrl)}\");\n        }\n\n        private void txtRunningInfoDisplay_MouseDoubleClick(object sender, MouseButtonEventArgs e)\n        {\n            ViewModel?.TestServerAvailability();\n        }\n\n        private void menuSettingsSetUWP_Click(object sender, RoutedEventArgs e)\n        {\n            Utils.ProcessStart(Utils.GetBinPath(\"EnableLoopback.exe\"));\n        }\n\n        private void BtnAutofitColumnWidth_Click(object sender, RoutedEventArgs e)\n        {\n            AutofitColumnWidth();\n        }\n\n        private void AutofitColumnWidth()\n        {\n            foreach (var it in lstProfiles.Columns)\n            {\n                it.Width = new DataGridLength(1, DataGridLengthUnitType.Auto);\n            }\n        }\n\n        private void TxtServerFilter_PreviewKeyDown(object sender, KeyEventArgs e)\n        {\n            if (e.Key is Key.Enter or Key.Return)\n            {\n                ViewModel?.RefreshServers();\n            }\n        }\n\n        #endregion Event\n\n        #region UI\n\n        private void RestoreUI()\n        {\n            if (_config.uiItem.mainWidth > 0 && _config.uiItem.mainHeight > 0)\n            {\n                Width = _config.uiItem.mainWidth;\n                Height = _config.uiItem.mainHeight;\n            }\n\n            var maxWidth = SystemParameters.WorkArea.Width;\n            var maxHeight = SystemParameters.WorkArea.Height;\n            if (Width > maxWidth) Width = maxWidth;\n            if (Height > maxHeight) Height = maxHeight;\n            if (_config.uiItem.mainGirdHeight1 > 0 && _config.uiItem.mainGirdHeight2 > 0)\n            {\n                gridMain.RowDefinitions[0].Height = new GridLength(_config.uiItem.mainGirdHeight1, GridUnitType.Star);\n                gridMain.RowDefinitions[2].Height = new GridLength(_config.uiItem.mainGirdHeight2, GridUnitType.Star);\n            }\n\n            var lvColumnItem = _config.uiItem.mainColumnItem.OrderBy(t => t.Index).ToList();\n            for (int i = 0; i < lvColumnItem.Count; i++)\n            {\n                var item = lvColumnItem[i];\n                for (int k = 1; k < lstProfiles.Columns.Count; k++)\n                {\n                    var item2 = (MyDGTextColumn)lstProfiles.Columns[k];\n                    if (item2.ExName == item.Name)\n                    {\n                        if (item.Width < 0)\n                        {\n                            item2.Visibility = Visibility.Hidden;\n                        }\n                        else\n                        {\n                            item2.Width = item.Width;\n                            item2.DisplayIndex = i;\n                        }\n                    }\n                }\n            }\n\n            if (!_config.guiItem.enableStatistics)\n            {\n                colTodayUp.Visibility = Visibility.Hidden;\n                colTodayDown.Visibility = Visibility.Hidden;\n                colTotalUp.Visibility = Visibility.Hidden;\n                colTotalDown.Visibility = Visibility.Hidden;\n            }\n        }\n\n        private void StorageUI()\n        {\n            _config.uiItem.mainWidth = this.Width;\n            _config.uiItem.mainHeight = this.Height;\n\n            List<ColumnItem> lvColumnItem = new();\n            for (int k = 0; k < lstProfiles.Columns.Count; k++)\n            {\n                var item2 = (MyDGTextColumn)lstProfiles.Columns[k];\n                lvColumnItem.Add(new()\n                {\n                    Name = item2.ExName,\n                    Width = item2.Visibility == Visibility.Visible ? Convert.ToInt32(item2.ActualWidth) : -1,\n                    Index = item2.DisplayIndex\n                });\n            }\n            _config.uiItem.mainColumnItem = lvColumnItem;\n\n            _config.uiItem.mainGirdHeight1 = Math.Ceiling(gridMain.RowDefinitions[0].ActualHeight + 0.1);\n            _config.uiItem.mainGirdHeight2 = Math.Ceiling(gridMain.RowDefinitions[2].ActualHeight + 0.1);\n        }\n\n        private void AddHelpMenuItem()\n        {\n            var coreInfos = LazyConfig.Instance.GetCoreInfos();\n            foreach (var it in coreInfos)\n            {\n                var item = new MenuItem()\n                {\n                    Tag = it.coreUrl.Replace(@\"/releases\", \"\"),\n                    Header = string.Format(Resx.ResUI.menuWebsiteItem, it.coreType.ToString().Replace(\"_\", \" \"))\n                };\n                item.Click += MenuItem_Click;\n                menuHelp.Items.Add(item);\n            }\n        }\n\n        private void MenuItem_Click(object sender, RoutedEventArgs e)\n        {\n            if (sender is MenuItem item)\n            {\n                Utils.ProcessStart(item.Tag.ToString());\n            }\n        }\n\n        #endregion UI\n\n        #region Drag and Drop\n\n        private Point startPoint = new();\n        private int startIndex = -1;\n        private string formatData = \"ProfileItemModel\";\n\n        /// <summary>\n        /// Helper to search up the VisualTree\n        /// </summary>\n        /// <typeparam name=\"T\"></typeparam>\n        /// <param name=\"current\"></param>\n        /// <returns></returns>\n        private static T? FindAnchestor<T>(DependencyObject current) where T : DependencyObject\n        {\n            do\n            {\n                if (current is T)\n                {\n                    return (T)current;\n                }\n                current = VisualTreeHelper.GetParent(current);\n            }\n            while (current != null);\n            return null;\n        }\n\n        private void LstProfiles_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)\n        {\n            // Get current mouse position\n            startPoint = e.GetPosition(null);\n        }\n\n        private void LstProfiles_MouseMove(object sender, MouseEventArgs e)\n        {\n            // Get the current mouse position\n            Point mousePos = e.GetPosition(null);\n            Vector diff = startPoint - mousePos;\n\n            if (e.LeftButton == MouseButtonState.Pressed &&\n                (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||\n                       Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))\n            {\n                // Get the dragged Item\n                if (sender is not DataGrid listView) return;\n                var listViewItem = FindAnchestor<DataGridRow>((DependencyObject)e.OriginalSource);\n                if (listViewItem == null) return;           // Abort\n                                                            // Find the data behind the ListViewItem\n                ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);\n                if (item == null) return;                   // Abort\n                                                            // Initialize the drag & drop operation\n                startIndex = lstProfiles.SelectedIndex;\n                DataObject dragData = new(formatData, item);\n                DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Copy | DragDropEffects.Move);\n            }\n        }\n\n        private void LstProfiles_DragEnter(object sender, DragEventArgs e)\n        {\n            if (!e.Data.GetDataPresent(formatData) || sender != e.Source)\n            {\n                e.Effects = DragDropEffects.None;\n            }\n        }\n\n        private void LstProfiles_Drop(object sender, DragEventArgs e)\n        {\n            if (e.Data.GetDataPresent(formatData) && sender == e.Source)\n            {\n                // Get the drop Item destination\n                if (sender is not DataGrid listView) return;\n                var listViewItem = FindAnchestor<DataGridRow>((DependencyObject)e.OriginalSource);\n                if (listViewItem == null)\n                {\n                    // Abort\n                    e.Effects = DragDropEffects.None;\n                    return;\n                }\n                // Find the data behind the Item\n                ProfileItemModel item = (ProfileItemModel)listView.ItemContainerGenerator.ItemFromContainer(listViewItem);\n                if (item == null) return;\n                // Move item into observable collection\n                // (this will be automatically reflected to lstView.ItemsSource)\n                e.Effects = DragDropEffects.Move;\n\n                ViewModel?.MoveServerTo(startIndex, item);\n\n                startIndex = -1;\n            }\n        }\n\n\n        #endregion\n\n        private void togEnableTun_Click(object sender, RoutedEventArgs e)\n        {\n            if (Utils.IsAdministrator())\n            {\n                togEnableProxy.IsChecked = togEnableTun.IsChecked;\n            }\n            else\n            {\n                UI.ShowError(ResUI.MsgStartProgramAsAdmin);\n                togEnableTun.IsChecked = false;\n            }\n        }\n\n        private void togEnableProxy_Click(object sender, RoutedEventArgs e)\n        {\n            // @hiddify it's just for proxy, i think we shoudn't check for Administrator right (it will work anyway)\n            //if (Utils.IsAdministrator())\n            //{\n            //    togEnableTun.IsChecked = togEnableProxy.IsChecked;\n            //}\n            //else\n            //{\n            //}\n            ViewModel.ToggleSysProxy();\n            //cmbSystemProxy.SelectedIndex = togEnableProxy.IsChecked==true ? 1 : 0;\n        }\n\n\n        private void ResizeWindowToFirstColumn()\n        {\n            // Get the actual width of the first column\n            double firstColumnWidth = HiddifyUI.ActualWidth;\n\n            // Add some padding to the width (optional)\n            double padding = 20;\n            double newWidth = firstColumnWidth + padding;\n\n            // Set the new window size\n            this.Width = newWidth;\n        }\n\n        // Example usage: resize the window to fit the first column\n        private void HideBtn_Click(object sender, RoutedEventArgs e)\n        {\n            //V2rayNPanel.Visibility=Visibility.Collapsed;\n            //ResizeWindowToFirstColumn();\n            \n        }\n\n        private void HiddifyUI_Loaded(object sender, RoutedEventArgs e)\n        {\n\n        }\n\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/MsgView.xaml",
    "content": "<UserControl\n    x:Class=\"v2rayN.Views.MsgView\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:local=\"clr-namespace:v2rayN.Views\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    d:DesignHeight=\"450\"\n    d:DesignWidth=\"800\"\n    mc:Ignorable=\"d\">\n    <DockPanel Margin=\"2\">\n        <StackPanel\n            VerticalAlignment=\"Center\"\n            DockPanel.Dock=\"Top\"\n            Orientation=\"Horizontal\">\n            <TextBlock\n                Margin=\"8,0\"\n                VerticalAlignment=\"Center\"\n                Foreground=\"{DynamicResource PrimaryHueLightBrush}\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.MsgInformationTitle}\" />\n            <ComboBox\n                x:Name=\"cmbMsgFilter\"\n                Width=\"200\"\n                Margin=\"8,0\"\n                materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.MsgFilterTitle}\"\n                materialDesign:TextFieldAssist.HasClearButton=\"True\"\n                IsEditable=\"True\"\n                Style=\"{StaticResource DefComboBox}\"\n                TextBoxBase.TextChanged=\"cmbMsgFilter_TextChanged\" />\n            <TextBlock\n                Margin=\"8,0\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.TbAutoRefresh}\" />\n            <ToggleButton\n                x:Name=\"togAutoRefresh\"\n                Margin=\"8,0\"\n                HorizontalAlignment=\"Left\"\n                IsChecked=\"True\" />\n        </StackPanel>\n        <TextBox\n            Name=\"txtMsg\"\n            BorderThickness=\"0\"\n            FontSize=\"{DynamicResource StdFontSizeMsg}\"\n            HorizontalScrollBarVisibility=\"Auto\"\n            IsReadOnly=\"True\"\n            IsReadOnlyCaretVisible=\"True\"\n            TextAlignment=\"Left\"\n            TextWrapping=\"Wrap\"\n            VerticalScrollBarVisibility=\"Visible\">\n            <TextBox.ContextMenu>\n                <ContextMenu Style=\"{StaticResource DefContextMenu}\">\n                    <MenuItem\n                        x:Name=\"menuMsgViewSelectAll\"\n                        Height=\"{StaticResource MenuItemHeight}\"\n                        Click=\"menuMsgViewSelectAll_Click\"\n                        Header=\"{x:Static resx:ResUI.menuMsgViewSelectAll}\" />\n                    <MenuItem\n                        x:Name=\"menuMsgViewCopy\"\n                        Height=\"{StaticResource MenuItemHeight}\"\n                        Click=\"menuMsgViewCopy_Click\"\n                        Header=\"{x:Static resx:ResUI.menuMsgViewCopy}\" />\n                    <MenuItem\n                        x:Name=\"menuMsgViewCopyAll\"\n                        Height=\"{StaticResource MenuItemHeight}\"\n                        Click=\"menuMsgViewCopyAll_Click\"\n                        Header=\"{x:Static resx:ResUI.menuMsgViewCopyAll}\" />\n                    <MenuItem\n                        x:Name=\"menuMsgViewClear\"\n                        Height=\"{StaticResource MenuItemHeight}\"\n                        Click=\"menuMsgViewClear_Click\"\n                        Header=\"{x:Static resx:ResUI.menuMsgViewClear}\" />\n                </ContextMenu>\n            </TextBox.ContextMenu>\n        </TextBox>\n    </DockPanel>\n</UserControl>"
  },
  {
    "path": "v2rayN/v2rayN/Views/MsgView.xaml.cs",
    "content": "using ReactiveUI;\nusing System.Reactive.Linq;\nusing System.Text.RegularExpressions;\nusing System.Windows.Threading;\nusing v2rayN.Base;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\n\nnamespace v2rayN.Views\n{\n    public partial class MsgView\n    {\n        private static Config _config;\n\n        private string lastMsgFilter;\n        private bool lastMsgFilterNotAvailable;\n\n        public MsgView()\n        {\n            InitializeComponent();\n            _config = LazyConfig.Instance.GetConfig();\n            MessageBus.Current.Listen<string>(\"MsgView\").Subscribe(x => DelegateAppendText(x));\n            Global.PresetMsgFilters.ForEach(it =>\n            {\n                cmbMsgFilter.Items.Add(it);\n            });\n            if (!_config.uiItem.mainMsgFilter.IsNullOrEmpty())\n            {\n                cmbMsgFilter.Text = _config.uiItem.mainMsgFilter;\n            }\n        }\n\n        private void DelegateAppendText(string msg)\n        {\n            Dispatcher.BeginInvoke(AppendText, DispatcherPriority.Send, msg);\n        }\n\n        public void AppendText(string msg)\n        {\n            if (msg == Global.CommandClearMsg)\n            {\n                ClearMsg();\n                return;\n            }\n            if (togAutoRefresh.IsChecked == false)\n            {\n                return;\n            }\n\n            var MsgFilter = cmbMsgFilter.Text.TrimEx();\n            if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false;\n            if (!string.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)\n            {\n                try\n                {\n                    if (!Regex.IsMatch(msg, MsgFilter)) // ʽ쳣\n                    {\n                        return;\n                    }\n                }\n                catch (Exception)\n                {\n                    lastMsgFilterNotAvailable = true;\n                }\n            }\n            lastMsgFilter = MsgFilter;\n\n            ShowMsg(msg);\n        }\n\n        private void ShowMsg(string msg)\n        {\n            if (txtMsg.LineCount > 999)\n            {\n                ClearMsg();\n            }\n            this.txtMsg.AppendText(msg);\n            if (!msg.EndsWith(Environment.NewLine))\n            {\n                this.txtMsg.AppendText(Environment.NewLine);\n            }\n            txtMsg.ScrollToEnd();\n        }\n\n        public void ClearMsg()\n        {\n            txtMsg.Clear();\n        }\n\n        private void menuMsgViewSelectAll_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            txtMsg.Focus();\n            txtMsg.SelectAll();\n        }\n\n        private void menuMsgViewCopy_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            var data = txtMsg.SelectedText.TrimEx();\n            Utils.SetClipboardData(data);\n        }\n\n        private void menuMsgViewCopyAll_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            var data = txtMsg.Text;\n            Utils.SetClipboardData(data);\n        }\n\n        private void menuMsgViewClear_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            ClearMsg();\n        }\n\n        private void cmbMsgFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)\n        {\n            _config.uiItem.mainMsgFilter = cmbMsgFilter.Text.TrimEx();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/OptionSettingWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.OptionSettingWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuSetting}\"\n    Width=\"1000\"\n    Height=\"700\"\n    x:TypeArguments=\"vms:OptionSettingViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <DockPanel Margin=\"8\">\n        <Grid HorizontalAlignment=\"Center\" DockPanel.Dock=\"Bottom\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"200\" />\n                <ColumnDefinition Width=\"200\" />\n            </Grid.ColumnDefinitions>\n            <Button\n                x:Name=\"btnSave\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                Cursor=\"Hand\"\n                Style=\"{StaticResource DefButton}\" />\n            <Button\n                x:Name=\"btnCancel\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                Click=\"btnCancel_Click\"\n                Content=\"{x:Static resx:ResUI.TbCancel}\"\n                Cursor=\"Hand\"\n                IsCancel=\"true\"\n                Style=\"{StaticResource DefButton}\" />\n        </Grid>\n\n        <TabControl HorizontalContentAlignment=\"Left\">\n            <TabItem Header=\"{x:Static resx:ResUI.TbSettingsCore}\">\n                <ScrollViewer VerticalScrollBarVisibility=\"Visible\">\n                    <Grid Margin=\"{StaticResource SettingItemMargin}\">\n                        <Grid.RowDefinitions>\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                        </Grid.RowDefinitions>\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"Auto\" />\n                            <ColumnDefinition Width=\"Auto\" />\n                            <ColumnDefinition Width=\"Auto\" />\n                        </Grid.ColumnDefinitions>\n\n                        <TextBlock\n                            Grid.Row=\"0\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsSocksPort}\" />\n                        <TextBox\n                            x:Name=\"txtlocalPort\"\n                            Grid.Row=\"0\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            Style=\"{StaticResource DefTextBox}\" />\n                        <TextBlock\n                            Grid.Row=\"0\"\n                            Grid.Column=\"2\"\n                            Margin=\"{StaticResource ServerItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsSocksPortTip}\" />\n\n                        <TextBlock\n                            Grid.Row=\"1\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsUdpEnabled}\" />\n                        <ToggleButton\n                            x:Name=\"togudpEnabled\"\n                            Grid.Row=\"1\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"2\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsSniffingEnabled}\" />\n                        <ToggleButton\n                            x:Name=\"togsniffingEnabled\"\n                            Grid.Row=\"2\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"3\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsRouteOnly}\" />\n                        <ToggleButton\n                            x:Name=\"togrouteOnly\"\n                            Grid.Row=\"3\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"4\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsAllowLAN}\" />\n                        <ToggleButton\n                            x:Name=\"togAllowLANConn\"\n                            Grid.Row=\"4\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"5\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsNewPort4LAN}\" />\n                        <ToggleButton\n                            x:Name=\"togNewPort4LAN\"\n                            Grid.Row=\"5\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"6\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsUser}\" />\n                        <TextBox\n                            x:Name=\"txtuser\"\n                            Grid.Row=\"6\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            Style=\"{StaticResource DefTextBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"7\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsPass}\" />\n                        <TextBox\n                            x:Name=\"txtpass\"\n                            Grid.Row=\"7\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            Style=\"{StaticResource DefTextBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"8\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsMuxEnabled}\" />\n                        <ToggleButton\n                            x:Name=\"togmuxEnabled\"\n                            Grid.Row=\"8\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"9\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsLogEnabledToFile}\" />\n                        <ToggleButton\n                            x:Name=\"toglogEnabled\"\n                            Grid.Row=\"9\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"10\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsLogLevel}\" />\n                        <ComboBox\n                            x:Name=\"cmbloglevel\"\n                            Grid.Row=\"10\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            materialDesign:HintAssist.Hint=\"Level\"\n                            Style=\"{StaticResource DefComboBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"11\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsDefAllowInsecure}\" />\n                        <ToggleButton\n                            x:Name=\"togdefAllowInsecure\"\n                            Grid.Row=\"11\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"12\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsDefFingerprint}\" />\n                        <ComboBox\n                            x:Name=\"cmbdefFingerprint\"\n                            Grid.Row=\"12\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            IsEditable=\"True\"\n                            Style=\"{StaticResource DefComboBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"13\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsDefUserAgent}\" />\n                        <ComboBox\n                            x:Name=\"cmbdefUserAgent\"\n                            Grid.Row=\"13\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            IsEditable=\"True\"\n                            Style=\"{StaticResource DefComboBox}\" />\n                        <TextBlock\n                            Grid.Row=\"13\"\n                            Grid.Column=\"3\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsDefUserAgentTips}\" />\n                    </Grid>\n                </ScrollViewer>\n            </TabItem>\n\n            <!--<TabItem Header=\"{x:Static resx:ResUI.TbSettingsCoreKcp}\">\n                <Grid Margin=\"{StaticResource SettingItemMargin}\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                    </Grid.RowDefinitions>\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition Width=\"Auto\" />\n                        <ColumnDefinition Width=\"Auto\" />\n                    </Grid.ColumnDefinitions>\n\n                    <TextBlock\n                        Grid.Row=\"1\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"mtu\" />\n                    <TextBox Style=\"{StaticResource DefTextBox}\"\n                        x:Name=\"txtKcpmtu\"\n                        Grid.Row=\"1\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\" />\n\n                    <TextBlock\n                        Grid.Row=\"2\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"tti\" />\n                    <TextBox Style=\"{StaticResource DefTextBox}\"\n                        x:Name=\"txtKcptti\"\n                        Grid.Row=\"2\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\" />\n\n                    <TextBlock\n                        Grid.Row=\"3\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"uplinkCapacity\" />\n                    <TextBox Style=\"{StaticResource DefTextBox}\"\n                        x:Name=\"txtKcpuplinkCapacity\"\n                        Grid.Row=\"3\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\" />\n\n                    <TextBlock\n                        Grid.Row=\"4\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"downlinkCapacity\" />\n                    <TextBox Style=\"{StaticResource DefTextBox}\"\n                        x:Name=\"txtKcpdownlinkCapacity\"\n                        Grid.Row=\"4\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\" />\n\n                    <TextBlock\n                        Grid.Row=\"5\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"readBufferSize\" />\n                    <TextBox Style=\"{StaticResource DefTextBox}\"\n                        x:Name=\"txtKcpreadBufferSize\"\n                        Grid.Row=\"5\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\" />\n\n                    <TextBlock\n                        Grid.Row=\"6\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"writeBufferSize\" />\n                    <TextBox Style=\"{StaticResource DefTextBox}\"\n                        x:Name=\"txtKcpwriteBufferSize\"\n                        Grid.Row=\"6\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\" />\n\n                    <TextBlock\n                        Grid.Row=\"7\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"congestion\" />\n                    <ToggleButton\n                        x:Name=\"togKcpcongestion\"\n                        Grid.Row=\"7\"\n                        Grid.Column=\"1\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        HorizontalAlignment=\"Left\" />\n                </Grid>\n            </TabItem>-->\n\n            <TabItem Header=\"{x:Static resx:ResUI.TbSettingsN}\">\n                <ScrollViewer VerticalScrollBarVisibility=\"Visible\">\n                    <Grid Grid.Row=\"2\" Margin=\"{StaticResource SettingItemMargin}\">\n                        <Grid.RowDefinitions>\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                        </Grid.RowDefinitions>\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"Auto\" />\n                            <ColumnDefinition Width=\"Auto\" />\n                            <ColumnDefinition Width=\"*\" />\n                        </Grid.ColumnDefinitions>\n\n                        <TextBlock\n                            Grid.Row=\"1\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsStartBoot}\" />\n                        <ToggleButton\n                            x:Name=\"togAutoRun\"\n                            Grid.Row=\"1\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n                        <TextBlock\n                            Grid.Row=\"1\"\n                            Grid.Column=\"2\"\n                            Margin=\"{StaticResource ServerItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsStartBootTip}\"\n                            TextWrapping=\"Wrap\" />\n\n                        <TextBlock\n                            Grid.Row=\"2\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsStatistics}\" />\n                        <ToggleButton\n                            x:Name=\"togEnableStatistics\"\n                            Grid.Row=\"2\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"3\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsStatisticsFreshRate}\" />\n                        <ComboBox\n                            x:Name=\"cmbStatisticsFreshRate\"\n                            Grid.Row=\"3\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            Style=\"{StaticResource DefComboBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"4\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsKeepOlderDedupl}\" />\n                        <ToggleButton\n                            x:Name=\"togKeepOlderDedupl\"\n                            Grid.Row=\"4\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"5\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsIgnoreGeoUpdateCore}\" />\n                        <ToggleButton\n                            x:Name=\"togIgnoreGeoUpdateCore\"\n                            Grid.Row=\"5\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"6\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsEnableAutoAdjustMainLvColWidth}\" />\n                        <ToggleButton\n                            x:Name=\"togEnableAutoAdjustMainLvColWidth\"\n                            Grid.Row=\"6\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"7\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsTLS13}\" />\n                        <ToggleButton\n                            x:Name=\"togEnableSecurityProtocolTls13\"\n                            Grid.Row=\"7\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"8\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsAutoHideStartup}\" />\n                        <ToggleButton\n                            x:Name=\"togAutoHideStartup\"\n                            Grid.Row=\"8\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"9\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsEnableCheckPreReleaseUpdate}\" />\n                        <ToggleButton\n                            x:Name=\"togEnableCheckPreReleaseUpdate\"\n                            Grid.Row=\"9\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"10\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsEnableDragDropSort}\" />\n                        <ToggleButton\n                            x:Name=\"togEnableDragDropSort\"\n                            Grid.Row=\"10\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"11\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsDoubleClick2Activate}\" />\n                        <ToggleButton\n                            x:Name=\"togDoubleClick2Activate\"\n                            Grid.Row=\"11\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"12\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsAutoUpdateInterval}\" />\n                        <TextBox\n                            x:Name=\"txtautoUpdateInterval\"\n                            Grid.Row=\"12\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\"\n                            Style=\"{StaticResource DefTextBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"14\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsTrayMenuServersLimit}\" />\n                        <TextBox\n                            x:Name=\"txttrayMenuServersLimit\"\n                            Grid.Row=\"14\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\"\n                            Style=\"{StaticResource DefTextBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"15\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsCurrentFontFamily}\" />\n                        <ComboBox\n                            x:Name=\"cmbcurrentFontFamily\"\n                            Grid.Row=\"15\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            MaxDropDownHeight=\"1000\"\n                            Style=\"{StaticResource DefComboBox}\" />\n                        <TextBlock\n                            Grid.Row=\"15\"\n                            Grid.Column=\"2\"\n                            Margin=\"{StaticResource ServerItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsCurrentFontFamilyTip}\"\n                            TextWrapping=\"Wrap\" />\n\n                        <TextBlock\n                            Grid.Row=\"16\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsSpeedTestTimeout}\" />\n                        <ComboBox\n                            x:Name=\"cmbSpeedTestTimeout\"\n                            Grid.Row=\"16\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            Style=\"{StaticResource DefComboBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"17\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsSpeedTestUrl}\" />\n                        <ComboBox\n                            x:Name=\"cmbSpeedTestUrl\"\n                            Grid.Row=\"17\"\n                            Grid.Column=\"1\"\n                            Width=\"300\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            IsEditable=\"True\"\n                            Style=\"{StaticResource DefComboBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"18\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsEnableHWA}\" />\n                        <ToggleButton\n                            x:Name=\"togEnableHWA\"\n                            Grid.Row=\"18\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"19\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsSubConvert}\" />\n                        <ComboBox\n                            x:Name=\"cmbSubConvertUrl\"\n                            Grid.Row=\"19\"\n                            Grid.Column=\"1\"\n                            Width=\"300\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            materialDesign:HintAssist.Hint=\"Convert Url\"\n                            IsEditable=\"True\"\n                            Style=\"{StaticResource DefComboBox}\" />\n                    </Grid>\n                </ScrollViewer>\n            </TabItem>\n\n            <TabItem Header=\"{x:Static resx:ResUI.TbSettingsSystemproxy}\">\n                <DockPanel Margin=\"{StaticResource SettingItemMargin}\">\n                    <StackPanel DockPanel.Dock=\"Bottom\" Orientation=\"Vertical\">\n                        <TextBlock\n                            Grid.Row=\"3\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsAdvancedProtocol}\" />\n                        <ComboBox\n                            x:Name=\"cmbsystemProxyAdvancedProtocol\"\n                            Grid.Row=\"4\"\n                            MinWidth=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            materialDesign:HintAssist.Hint=\"Protocol\"\n                            Style=\"{StaticResource DefComboBox}\" />\n                    </StackPanel>\n\n                    <TextBlock\n                        Grid.Row=\"1\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        DockPanel.Dock=\"Top\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"{x:Static resx:ResUI.TbSettingsExceptionTip}\" />\n                    <TextBox\n                        x:Name=\"txtsystemProxyExceptions\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Stretch\"\n                        AcceptsReturn=\"True\"\n                        BorderThickness=\"1\"\n                        Style=\"{StaticResource DefTextBox}\"\n                        TextWrapping=\"Wrap\"\n                        VerticalScrollBarVisibility=\"Auto\" />\n                </DockPanel>\n            </TabItem>\n\n            <TabItem Header=\"{x:Static resx:ResUI.TbSettingsTunMode}\">\n                <DockPanel Margin=\"{StaticResource SettingItemMargin}\">\n                    <Grid Margin=\"{StaticResource SettingItemMargin}\" DockPanel.Dock=\"Top\">\n                        <Grid.RowDefinitions>\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                            <RowDefinition Height=\"Auto\" />\n                        </Grid.RowDefinitions>\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"Auto\" />\n                            <ColumnDefinition Width=\"Auto\" />\n                            <ColumnDefinition Width=\"Auto\" />\n                        </Grid.ColumnDefinitions>\n\n                        <TextBlock\n                            Grid.Row=\"0\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsTunModeShowWindow}\" />\n                        <ToggleButton\n                            x:Name=\"togShowWindow\"\n                            Grid.Row=\"0\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"1\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsLogEnabled}\" />\n                        <ToggleButton\n                            x:Name=\"togEnabledLog\"\n                            Grid.Row=\"1\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"2\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"Strict Route\" />\n                        <ToggleButton\n                            x:Name=\"togStrictRoute\"\n                            Grid.Row=\"2\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n\n                        <TextBlock\n                            Grid.Row=\"3\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"Stack\" />\n                        <ComboBox\n                            x:Name=\"cmbStack\"\n                            Grid.Row=\"3\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\"\n                            Style=\"{StaticResource DefComboBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"4\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"Mtu\" />\n                        <ComboBox\n                            x:Name=\"cmbMtu\"\n                            Grid.Row=\"4\"\n                            Grid.Column=\"1\"\n                            Width=\"200\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\"\n                            Style=\"{StaticResource DefComboBox}\" />\n\n                        <TextBlock\n                            Grid.Row=\"5\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsTunModeCustomTemplate}\" />\n                        <TextBox\n                            x:Name=\"txtCustomTemplate\"\n                            Grid.Row=\"5\"\n                            Grid.Column=\"1\"\n                            Width=\"400\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Top\"\n                            AcceptsReturn=\"True\"\n                            Style=\"{StaticResource DefTextBox}\"\n                            TextWrapping=\"Wrap\" />\n                        <Button\n                            x:Name=\"btnBrowse\"\n                            Grid.Row=\"5\"\n                            Grid.Column=\"2\"\n                            Width=\"100\"\n                            Margin=\"2,0,8,0\"\n                            Click=\"btnBrowse_Click\"\n                            Content=\"{x:Static resx:ResUI.TbBrowse}\"\n                            Style=\"{StaticResource DefButton}\" />\n\n                        <TextBlock\n                            Grid.Row=\"6\"\n                            Grid.Column=\"0\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsTunModeBypassMode}\" />\n                        <ToggleButton\n                            x:Name=\"togBypassMode\"\n                            Grid.Row=\"6\"\n                            Grid.Column=\"1\"\n                            Margin=\"{StaticResource SettingItemMargin}\"\n                            HorizontalAlignment=\"Left\" />\n                        <TextBlock\n                            Grid.Row=\"6\"\n                            Grid.Column=\"2\"\n                            Margin=\"{StaticResource ServerItemMargin}\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.TbSettingsTunModeBypassModeTip}\" />\n                    </Grid>\n\n                    <Grid\n                        x:Name=\"gridTunModeDirect\"\n                        Width=\"800\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        HorizontalAlignment=\"Left\">\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"2*\" />\n                            <ColumnDefinition Width=\"5\" />\n                            <ColumnDefinition Width=\"2*\" />\n                            <ColumnDefinition Width=\"5\" />\n                            <ColumnDefinition Width=\"3*\" />\n                        </Grid.ColumnDefinitions>\n                        <GroupBox\n                            Grid.Column=\"0\"\n                            Header=\"{x:Static resx:ResUI.TbSettingsTunModeDirectIP}\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtDirectIP\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                        <GridSplitter Grid.Column=\"1\" HorizontalAlignment=\"Stretch\" />\n                        <GroupBox\n                            Grid.Column=\"2\"\n                            Header=\"{x:Static resx:ResUI.TbSettingsTunModeDirectProcess}\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtDirectProcess\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                        <GridSplitter Grid.Column=\"3\" HorizontalAlignment=\"Stretch\" />\n                        <GroupBox\n                            Grid.Column=\"4\"\n                            Header=\"{x:Static resx:ResUI.TbSettingsTunModeDNS}\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtDirectDNS\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                    </Grid>\n\n                    <Grid\n                        x:Name=\"gridTunModeProxy\"\n                        Width=\"800\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        HorizontalAlignment=\"Left\">\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"2*\" />\n                            <ColumnDefinition Width=\"5\" />\n                            <ColumnDefinition Width=\"2*\" />\n                            <ColumnDefinition Width=\"5\" />\n                            <ColumnDefinition Width=\"3*\" />\n                        </Grid.ColumnDefinitions>\n                        <GroupBox\n                            Grid.Column=\"0\"\n                            Header=\"{x:Static resx:ResUI.TbSettingsTunModeProxyIP}\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtProxyIP\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                        <GridSplitter Grid.Column=\"1\" HorizontalAlignment=\"Stretch\" />\n                        <GroupBox\n                            Grid.Column=\"2\"\n                            Header=\"{x:Static resx:ResUI.TbSettingsTunModeProxyProcess}\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtProxyProcess\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                        <GridSplitter Grid.Column=\"3\" HorizontalAlignment=\"Stretch\" />\n                        <GroupBox\n                            Grid.Column=\"4\"\n                            Header=\"{x:Static resx:ResUI.TbSettingsTunModeDNS}\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtProxyDNS\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                    </Grid>\n                </DockPanel>\n            </TabItem>\n\n            <TabItem Header=\"{x:Static resx:ResUI.TbSettingsCoreType}\">\n                <Grid Margin=\"{StaticResource SettingItemMargin}\">\n                    <Grid.RowDefinitions>\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                        <RowDefinition Height=\"Auto\" />\n                    </Grid.RowDefinitions>\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition Width=\"Auto\" />\n                        <ColumnDefinition Width=\"Auto\" />\n                    </Grid.ColumnDefinitions>\n                    <TextBlock\n                        Grid.Row=\"1\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"VMess\" />\n                    <ComboBox\n                        x:Name=\"cmbCoreType1\"\n                        Grid.Row=\"1\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        Style=\"{StaticResource DefComboBox}\" />\n\n                    <TextBlock\n                        Grid.Row=\"2\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"Custom\" />\n                    <ComboBox\n                        x:Name=\"cmbCoreType2\"\n                        Grid.Row=\"2\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        Style=\"{StaticResource DefComboBox}\" />\n\n                    <TextBlock\n                        Grid.Row=\"3\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"Shadowsocks\" />\n                    <ComboBox\n                        x:Name=\"cmbCoreType3\"\n                        Grid.Row=\"3\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        Style=\"{StaticResource DefComboBox}\" />\n\n                    <TextBlock\n                        Grid.Row=\"4\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"Socks\" />\n                    <ComboBox\n                        x:Name=\"cmbCoreType4\"\n                        Grid.Row=\"4\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        Style=\"{StaticResource DefComboBox}\" />\n\n                    <TextBlock\n                        Grid.Row=\"5\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"VLESS\" />\n                    <ComboBox\n                        x:Name=\"cmbCoreType5\"\n                        Grid.Row=\"5\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        Style=\"{StaticResource DefComboBox}\" />\n\n                    <TextBlock\n                        Grid.Row=\"6\"\n                        Grid.Column=\"0\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        VerticalAlignment=\"Center\"\n                        Style=\"{StaticResource ToolbarTextBlock}\"\n                        Text=\"Trojan\" />\n                    <ComboBox\n                        x:Name=\"cmbCoreType6\"\n                        Grid.Row=\"6\"\n                        Grid.Column=\"1\"\n                        Width=\"200\"\n                        Margin=\"{StaticResource SettingItemMargin}\"\n                        Style=\"{StaticResource DefComboBox}\" />\n                </Grid>\n            </TabItem>\n        </TabControl>\n    </DockPanel>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs",
    "content": "﻿using Microsoft.Win32;\nusing ReactiveUI;\nusing System.Globalization;\nusing System.IO;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing System.Windows.Media;\nusing v2rayN.Handler;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class OptionSettingWindow\n    {\n        private static Config _config;\n\n        public OptionSettingWindow()\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            _config = LazyConfig.Instance.GetConfig();\n\n            ViewModel = new OptionSettingViewModel(this);\n\n            Global.IEProxyProtocols.ForEach(it =>\n            {\n                cmbsystemProxyAdvancedProtocol.Items.Add(it);\n            });\n            Global.LogLevel.ForEach(it =>\n            {\n                cmbloglevel.Items.Add(it);\n            });\n            Global.fingerprints.ForEach(it =>\n            {\n                cmbdefFingerprint.Items.Add(it);\n            });\n            Global.userAgent.ForEach(it =>\n            {\n                cmbdefUserAgent.Items.Add(it);\n            });\n\n            for (int i = 1; i <= 10; i++)\n            {\n                cmbStatisticsFreshRate.Items.Add(i);\n            }\n            Global.TunMtus.ForEach(it =>\n            {\n                cmbMtu.Items.Add(it);\n            });\n            Global.TunStacks.ForEach(it =>\n            {\n                cmbStack.Items.Add(it);\n            });\n            Global.coreTypes.ForEach(it =>\n            {\n                cmbCoreType1.Items.Add(it);\n                cmbCoreType2.Items.Add(it);\n                cmbCoreType3.Items.Add(it);\n                cmbCoreType4.Items.Add(it);\n                cmbCoreType5.Items.Add(it);\n                cmbCoreType6.Items.Add(it);\n            });\n\n            for (int i = 2; i <= 6; i++)\n            {\n                cmbSpeedTestTimeout.Items.Add(i * 5);\n            }\n            Global.SpeedTestUrls.ForEach(it =>\n            {\n                cmbSpeedTestUrl.Items.Add(it);\n            });\n            Global.SubConvertUrls.ForEach(it =>\n            {\n                cmbSubConvertUrl.Items.Add(it);\n            });\n\n            //fill fonts\n            try\n            {\n                var files = Directory.GetFiles(Utils.GetFontsPath(), \"*.ttf\");\n                var culture = _config.uiItem.currentLanguage == Global.Languages[0] ? \"zh-cn\" : \"en-us\";\n                var culture2 = \"en-us\";\n                foreach (var ttf in files)\n                {\n                    var families = Fonts.GetFontFamilies(Utils.GetFontsPath(ttf));\n                    foreach (FontFamily family in families)\n                    {\n                        var typefaces = family.GetTypefaces();\n                        foreach (Typeface typeface in typefaces)\n                        {\n                            typeface.TryGetGlyphTypeface(out GlyphTypeface glyph);\n                            //var fontFace = glyph.Win32FaceNames[new CultureInfo(\"en-us\")];\n                            //if (!fontFace.Equals(\"Regular\") && !fontFace.Equals(\"Normal\"))\n                            //{\n                            //    continue;\n                            //}\n                            var fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture)];\n                            if (Utils.IsNullOrEmpty(fontFamily))\n                            {\n                                fontFamily = glyph.Win32FamilyNames[new CultureInfo(culture2)];\n                                if (Utils.IsNullOrEmpty(fontFamily))\n                                {\n                                    continue;\n                                }\n                            }\n                            cmbcurrentFontFamily.Items.Add(fontFamily);\n                            break;\n                        }\n                    }\n                }\n            }\n            catch (Exception ex)\n            {\n                Utils.SaveLog(\"fill fonts error\", ex);\n            }\n            cmbcurrentFontFamily.Items.Add(string.Empty);\n\n            this.WhenActivated(disposables =>\n            {\n                this.Bind(ViewModel, vm => vm.localPort, v => v.txtlocalPort.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.udpEnabled, v => v.togudpEnabled.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.sniffingEnabled, v => v.togsniffingEnabled.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.routeOnly, v => v.togrouteOnly.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.allowLANConn, v => v.togAllowLANConn.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.newPort4LAN, v => v.togNewPort4LAN.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.newPort4LAN, v => v.txtuser.IsEnabled).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.newPort4LAN, v => v.txtpass.IsEnabled).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.user, v => v.txtuser.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.pass, v => v.txtpass.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.muxEnabled, v => v.togmuxEnabled.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.logEnabled, v => v.toglogEnabled.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.loglevel, v => v.cmbloglevel.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.defAllowInsecure, v => v.togdefAllowInsecure.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.defFingerprint, v => v.cmbdefFingerprint.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.defUserAgent, v => v.cmbdefUserAgent.Text).DisposeWith(disposables);\n\n                //this.Bind(ViewModel, vm => vm.Kcpmtu, v => v.txtKcpmtu.Text).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.Kcptti, v => v.txtKcptti.Text).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.KcpuplinkCapacity, v => v.txtKcpuplinkCapacity.Text).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.KcpdownlinkCapacity, v => v.txtKcpdownlinkCapacity.Text).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.KcpreadBufferSize, v => v.txtKcpreadBufferSize.Text).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.KcpwriteBufferSize, v => v.txtKcpwriteBufferSize.Text).DisposeWith(disposables);\n                //this.Bind(ViewModel, vm => vm.Kcpcongestion, v => v.togKcpcongestion.IsChecked).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.AutoRun, v => v.togAutoRun.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.EnableStatistics, v => v.togEnableStatistics.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.StatisticsFreshRate, v => v.cmbStatisticsFreshRate.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.KeepOlderDedupl, v => v.togKeepOlderDedupl.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.IgnoreGeoUpdateCore, v => v.togIgnoreGeoUpdateCore.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.EnableAutoAdjustMainLvColWidth, v => v.togEnableAutoAdjustMainLvColWidth.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.EnableSecurityProtocolTls13, v => v.togEnableSecurityProtocolTls13.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.AutoHideStartup, v => v.togAutoHideStartup.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.EnableDragDropSort, v => v.togEnableDragDropSort.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.DoubleClick2Activate, v => v.togDoubleClick2Activate.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.autoUpdateInterval, v => v.txtautoUpdateInterval.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.trayMenuServersLimit, v => v.txttrayMenuServersLimit.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.currentFontFamily, v => v.cmbcurrentFontFamily.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SpeedTestTimeout, v => v.cmbSpeedTestTimeout.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SpeedTestUrl, v => v.cmbSpeedTestUrl.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.EnableHWA, v => v.togEnableHWA.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SubConvertUrl, v => v.cmbSubConvertUrl.Text).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.systemProxyAdvancedProtocol, v => v.cmbsystemProxyAdvancedProtocol.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.systemProxyExceptions, v => v.txtsystemProxyExceptions.Text).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.TunShowWindow, v => v.togShowWindow.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunEnabledLog, v => v.togEnabledLog.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunStrictRoute, v => v.togStrictRoute.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunStack, v => v.cmbStack.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunMtu, v => v.cmbMtu.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunCustomTemplate, v => v.txtCustomTemplate.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunBypassMode, v => v.togBypassMode.IsChecked).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.TunBypassMode, v => v.gridTunModeDirect.Visibility, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.TunBypassMode2, v => v.gridTunModeProxy.Visibility, vmToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunDirectIP, v => v.txtDirectIP.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunDirectProcess, v => v.txtDirectProcess.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunDirectDNS, v => v.txtDirectDNS.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunProxyIP, v => v.txtProxyIP.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunProxyProcess, v => v.txtProxyProcess.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.TunProxyDNS, v => v.txtProxyDNS.Text).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.CoreType1, v => v.cmbCoreType1.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.CoreType2, v => v.cmbCoreType2.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.CoreType3, v => v.cmbCoreType3.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.CoreType4, v => v.cmbCoreType4.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.CoreType5, v => v.cmbCoreType5.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.CoreType6, v => v.cmbCoreType6.Text).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);\n            });\n        }\n\n        private void btnCancel_Click(object sender, RoutedEventArgs e)\n        {\n            this.Close();\n        }\n\n        private void btnBrowse_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            var openFileDialog1 = new OpenFileDialog();\n            openFileDialog1.Filter = \"tunConfig|*.json|All|*.*\";\n            openFileDialog1.ShowDialog();\n\n            txtCustomTemplate.Text = openFileDialog1.FileName;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/QrcodeView.xaml",
    "content": "﻿<UserControl\n    x:Class=\"v2rayN.Views.QrcodeView\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    d:DesignHeight=\"300\"\n    d:DesignWidth=\"300\"\n    mc:Ignorable=\"d\">\n    <Grid Margin=\"30\">\n        <Grid.RowDefinitions>\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"Auto\" />\n            <RowDefinition Height=\"60\" />\n        </Grid.RowDefinitions>\n\n        <Image\n            x:Name=\"imgQrcode\"\n            Grid.Row=\"0\"\n            Width=\"300\"\n            Height=\"300\"\n            Stretch=\"UniformToFill\" />\n\n        <TextBox\n            x:Name=\"txtContent\"\n            Grid.Row=\"1\"\n            Width=\"300\"\n            Margin=\"0,8\"\n            VerticalAlignment=\"Center\"\n            IsReadOnly=\"True\"\n            MaxLines=\"3\"\n            TextWrapping=\"Wrap\"\n            VerticalScrollBarVisibility=\"Auto\" />\n\n        <Button\n            Grid.Row=\"2\"\n            Width=\"100\"\n            Margin=\"8\"\n            HorizontalAlignment=\"Right\"\n            Command=\"{x:Static materialDesign:DialogHost.CloseDialogCommand}\"\n            Content=\"{x:Static resx:ResUI.TbConfirm}\"\n            IsCancel=\"True\"\n            IsDefault=\"True\"\n            Style=\"{StaticResource MaterialDesignFlatButton}\" />\n    </Grid>\n</UserControl>"
  },
  {
    "path": "v2rayN/v2rayN/Views/QrcodeView.xaml.cs",
    "content": "﻿using System.Windows.Controls;\n\nnamespace v2rayN.Views\n{\n    public partial class QrcodeView : UserControl\n    {\n        public QrcodeView()\n        {\n            InitializeComponent();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.RoutingRuleDetailsWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}\"\n    Width=\"900\"\n    Height=\"700\"\n    x:TypeArguments=\"vms:RoutingRuleDetailsViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <DockPanel>\n        <Grid Margin=\"8\" DockPanel.Dock=\"Top\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n            </Grid.RowDefinitions>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"Auto\" />\n                <ColumnDefinition Width=\"Auto\" />\n            </Grid.ColumnDefinitions>\n            <TextBlock\n                Grid.Row=\"0\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"outboundTag\" />\n            <ComboBox\n                x:Name=\"cmbOutboundTag\"\n                Grid.Row=\"0\"\n                Grid.Column=\"1\"\n                Width=\"200\"\n                Margin=\"4\"\n                MaxDropDownHeight=\"1000\"\n                Style=\"{StaticResource DefComboBox}\" />\n\n            <TextBlock\n                Grid.Row=\"1\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"port\" />\n            <TextBox\n                x:Name=\"txtPort\"\n                Grid.Row=\"1\"\n                Grid.Column=\"1\"\n                Width=\"200\"\n                Margin=\"4\"\n                HorizontalAlignment=\"Left\"\n                Style=\"{StaticResource DefTextBox}\" />\n\n            <TextBlock\n                Grid.Row=\"2\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"protocol\" />\n            <ListBox\n                x:Name=\"clbProtocol\"\n                Grid.Row=\"2\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                HorizontalAlignment=\"Left\"\n                FontSize=\"{DynamicResource StdFontSize}\"\n                Style=\"{StaticResource MaterialDesignFilterChipPrimaryListBox}\" />\n\n            <TextBlock\n                Grid.Row=\"3\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"inboundTag\" />\n            <ListBox\n                x:Name=\"clbInboundTag\"\n                Grid.Row=\"3\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                FontSize=\"{DynamicResource StdFontSize}\"\n                Style=\"{StaticResource MaterialDesignFilterChipPrimaryListBox}\" />\n\n            <TextBlock\n                Grid.Row=\"4\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"enabled\" />\n            <ToggleButton\n                x:Name=\"togEnabled\"\n                Grid.Row=\"4\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                HorizontalAlignment=\"Left\" />\n\n            <TextBlock\n                Grid.Row=\"5\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\">\n                <Hyperlink Click=\"linkRuleobjectDoc_Click\">\n                    <TextBlock Text=\"{x:Static resx:ResUI.TbRuleobjectDoc}\" />\n                </Hyperlink>\n            </TextBlock>\n            <TextBlock\n                Grid.Row=\"5\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                HorizontalAlignment=\"Left\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.TbRoutingTips}\" />\n        </Grid>\n\n        <Grid\n            Margin=\"8\"\n            HorizontalAlignment=\"Center\"\n            DockPanel.Dock=\"Bottom\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"600\" />\n                <ColumnDefinition Width=\"100\" />\n                <ColumnDefinition Width=\"100\" />\n            </Grid.ColumnDefinitions>\n            <StackPanel\n                Grid.Column=\"0\"\n                HorizontalAlignment=\"Left\"\n                VerticalAlignment=\"Center\">\n                <CheckBox x:Name=\"chkAutoSort\">\n                    <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.TbAutoSort}\" />\n                </CheckBox>\n            </StackPanel>\n            <Button\n                x:Name=\"btnSave\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                Cursor=\"Hand\"\n                Style=\"{StaticResource DefButton}\" />\n            <Button\n                x:Name=\"btnCancel\"\n                Grid.Column=\"2\"\n                Margin=\"4\"\n                Content=\"{x:Static resx:ResUI.TbCancel}\"\n                Cursor=\"Hand\"\n                IsCancel=\"true\"\n                Style=\"{StaticResource DefButton}\" />\n        </Grid>\n\n        <Grid Margin=\"{StaticResource SettingItemMargin}\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"1*\" />\n                <ColumnDefinition Width=\"10\" />\n                <ColumnDefinition Width=\"1*\" />\n            </Grid.ColumnDefinitions>\n            <GroupBox\n                Grid.Column=\"0\"\n                Header=\"Domain\"\n                Style=\"{StaticResource MyGroupBox}\">\n                <TextBox\n                    Name=\"txtDomain\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource DefTextBox}\"\n                    TextWrapping=\"Wrap\"\n                    VerticalScrollBarVisibility=\"Auto\" />\n            </GroupBox>\n            <GridSplitter Grid.Column=\"1\" HorizontalAlignment=\"Stretch\" />\n            <GroupBox\n                Grid.Column=\"2\"\n                Header=\"IP\"\n                Style=\"{StaticResource MyGroupBox}\">\n                <TextBox\n                    Name=\"txtIP\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource DefTextBox}\"\n                    TextWrapping=\"Wrap\"\n                    VerticalScrollBarVisibility=\"Auto\" />\n            </GroupBox>\n        </Grid>\n    </DockPanel>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml.cs",
    "content": "﻿using ReactiveUI;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing v2rayN.Base;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class RoutingRuleDetailsWindow\n    {\n        public RoutingRuleDetailsWindow(RulesItem rulesItem)\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            this.Loaded += Window_Loaded;\n            clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged;\n            clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;\n\n            ViewModel = new RoutingRuleDetailsViewModel(rulesItem, this);\n            cmbOutboundTag.Items.Add(Global.agentTag);\n            cmbOutboundTag.Items.Add(Global.directTag);\n            cmbOutboundTag.Items.Add(Global.blockTag);\n            Global.Protocols.ForEach(it =>\n            {\n                clbProtocol.Items.Add(it);\n            });\n            Global.InboundTags.ForEach(it =>\n            {\n                clbInboundTag.Items.Add(it);\n            });\n\n            if (!rulesItem.id.IsNullOrEmpty())\n            {\n                rulesItem.protocol?.ForEach(it =>\n                {\n                    clbProtocol.SelectedItems.Add(it);\n                });\n                rulesItem.inboundTag?.ForEach(it =>\n                {\n                    clbInboundTag.SelectedItems.Add(it);\n                });\n            }\n\n            this.WhenActivated(disposables =>\n            {\n                this.Bind(ViewModel, vm => vm.SelectedSource.outboundTag, v => v.cmbOutboundTag.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.port, v => v.txtPort.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnabled.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.Domain, v => v.txtDomain.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.IP, v => v.txtIP.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.AutoSort, v => v.chkAutoSort.IsChecked).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);\n            });\n        }\n\n        private void Window_Loaded(object sender, RoutedEventArgs e)\n        {\n            cmbOutboundTag.Focus();\n        }\n\n        private void ClbProtocol_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)\n        {\n            ViewModel.ProtocolItems = clbProtocol.SelectedItems.Cast<string>().ToList();\n        }\n\n        private void ClbInboundTag_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)\n        {\n            ViewModel.InboundTagItems = clbInboundTag.SelectedItems.Cast<string>().ToList();\n        }\n\n        private void btnCancel_Click(object sender, RoutedEventArgs e)\n        {\n            this.Close();\n        }\n\n        private void linkRuleobjectDoc_Click(object sender, RoutedEventArgs e)\n        {\n            Utils.ProcessStart(\"https://www.v2fly.org/config/routing.html#ruleobject\");\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.RoutingRuleSettingWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuRoutingRuleSetting}\"\n    Width=\"900\"\n    Height=\"700\"\n    x:TypeArguments=\"vms:RoutingRuleSettingViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <DockPanel>\n        <ToolBarTray DockPanel.Dock=\"Top\">\n            <ToolBar\n                HorizontalAlignment=\"Center\"\n                VerticalAlignment=\"Center\"\n                ClipToBounds=\"True\"\n                Style=\"{StaticResource MaterialDesignToolBar}\">\n                <Button x:Name=\"menuRuleAdd\">\n                    <StackPanel Orientation=\"Horizontal\">\n                        <materialDesign:PackIcon\n                            Margin=\"0,0,8,0\"\n                            VerticalAlignment=\"Center\"\n                            Kind=\"Plus\" />\n                        <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuRuleAdd}\" />\n                    </StackPanel>\n                </Button>\n                <Separator />\n                <Button x:Name=\"menuImportRulesFromFile\">\n                    <StackPanel Orientation=\"Horizontal\">\n                        <materialDesign:PackIcon\n                            Margin=\"0,0,8,0\"\n                            VerticalAlignment=\"Center\"\n                            Kind=\"Import\" />\n                        <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuImportRulesFromFile}\" />\n                    </StackPanel>\n                </Button>\n                <Separator />\n                <Button x:Name=\"menuImportRulesFromClipboard\">\n                    <StackPanel Orientation=\"Horizontal\">\n                        <materialDesign:PackIcon\n                            Margin=\"0,0,8,0\"\n                            VerticalAlignment=\"Center\"\n                            Kind=\"Import\" />\n                        <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuImportRulesFromClipboard}\" />\n                    </StackPanel>\n                </Button>\n                <Separator />\n                <Button x:Name=\"menuImportRulesFromUrl\">\n                    <StackPanel Orientation=\"Horizontal\">\n                        <materialDesign:PackIcon\n                            Margin=\"0,0,8,0\"\n                            VerticalAlignment=\"Center\"\n                            Kind=\"Import\" />\n                        <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuImportRulesFromUrl}\" />\n                    </StackPanel>\n                </Button>\n            </ToolBar>\n        </ToolBarTray>\n\n        <Grid\n            Margin=\"8\"\n            HorizontalAlignment=\"Center\"\n            DockPanel.Dock=\"Bottom\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"600\" />\n                <ColumnDefinition Width=\"100\" />\n                <ColumnDefinition Width=\"100\" />\n            </Grid.ColumnDefinitions>\n            <Button\n                x:Name=\"btnSave\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                Cursor=\"Hand\"\n                Style=\"{StaticResource DefButton}\" />\n            <Button\n                x:Name=\"btnCancel\"\n                Grid.Column=\"2\"\n                Margin=\"4\"\n                Content=\"{x:Static resx:ResUI.TbCancel}\"\n                Cursor=\"Hand\"\n                IsCancel=\"true\"\n                Style=\"{StaticResource DefButton}\" />\n        </Grid>\n\n        <Grid Margin=\"8\" DockPanel.Dock=\"Top\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n            </Grid.RowDefinitions>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"Auto\" />\n                <ColumnDefinition Width=\"Auto\" />\n                <ColumnDefinition Width=\"Auto\" />\n            </Grid.ColumnDefinitions>\n            <TextBlock\n                Grid.Row=\"0\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.LvRemarks}\" />\n            <TextBox\n                x:Name=\"txtRemarks\"\n                Grid.Row=\"0\"\n                Grid.Column=\"1\"\n                Width=\"400\"\n                Margin=\"4\"\n                HorizontalAlignment=\"Left\"\n                VerticalAlignment=\"Top\"\n                AcceptsReturn=\"True\"\n                Style=\"{StaticResource DefTextBox}\"\n                TextWrapping=\"Wrap\" />\n\n            <TextBlock\n                Grid.Row=\"1\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.TbdomainStrategy}\" />\n            <StackPanel\n                Grid.Row=\"1\"\n                Grid.Column=\"1\"\n                Orientation=\"Horizontal\">\n                <ComboBox\n                    x:Name=\"cmbdomainStrategy\"\n                    Width=\"200\"\n                    Margin=\"4\"\n                    Style=\"{StaticResource DefComboBox}\" />\n                <TextBlock\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbdomainStrategy4Singbox}\" />\n                <ComboBox\n                    x:Name=\"cmbdomainStrategy4Singbox\"\n                    Width=\"200\"\n                    Margin=\"4\"\n                    Style=\"{StaticResource DefComboBox}\" />\n            </StackPanel>\n\n            <TextBlock\n                Grid.Row=\"2\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.LvUrl}\" />\n            <TextBox\n                x:Name=\"txtUrl\"\n                Grid.Row=\"2\"\n                Grid.Column=\"1\"\n                Width=\"600\"\n                Margin=\"4\"\n                VerticalAlignment=\"Top\"\n                AcceptsReturn=\"True\"\n                Style=\"{StaticResource DefTextBox}\"\n                TextWrapping=\"Wrap\" />\n\n            <TextBlock\n                Grid.Row=\"3\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.LvCustomIcon}\" />\n            <TextBox\n                x:Name=\"txtCustomIcon\"\n                Grid.Row=\"3\"\n                Grid.Column=\"1\"\n                Width=\"600\"\n                Margin=\"4\"\n                VerticalAlignment=\"Top\"\n                AcceptsReturn=\"True\"\n                Style=\"{StaticResource DefTextBox}\"\n                TextWrapping=\"Wrap\" />\n            <Button\n                x:Name=\"btnBrowse\"\n                Grid.Row=\"3\"\n                Grid.Column=\"2\"\n                Width=\"100\"\n                Margin=\"2,0,8,0\"\n                Click=\"btnBrowse_Click\"\n                Content=\"{x:Static resx:ResUI.TbBrowse}\"\n                Style=\"{StaticResource DefButton}\" />\n\n            <TextBlock\n                Grid.Row=\"4\"\n                Grid.Column=\"0\"\n                Margin=\"4\"\n                VerticalAlignment=\"Center\"\n                Style=\"{StaticResource ToolbarTextBlock}\"\n                Text=\"{x:Static resx:ResUI.LvSort}\" />\n            <TextBox\n                x:Name=\"txtSort\"\n                Grid.Row=\"4\"\n                Grid.Column=\"1\"\n                Width=\"200\"\n                Margin=\"4\"\n                HorizontalAlignment=\"Left\"\n                AcceptsReturn=\"True\"\n                Style=\"{StaticResource DefTextBox}\" />\n        </Grid>\n\n        <TabControl x:Name=\"tabAdvanced\">\n            <TabItem HorizontalAlignment=\"Left\" Header=\"{x:Static resx:ResUI.menuRuleList}\">\n                <DataGrid\n                    x:Name=\"lstRules\"\n                    AutoGenerateColumns=\"False\"\n                    BorderThickness=\"1\"\n                    CanUserAddRows=\"False\"\n                    CanUserResizeRows=\"False\"\n                    CanUserSortColumns=\"False\"\n                    EnableRowVirtualization=\"True\"\n                    GridLinesVisibility=\"All\"\n                    HeadersVisibility=\"Column\"\n                    IsReadOnly=\"True\"\n                    Style=\"{StaticResource DefDataGrid}\">\n                    <DataGrid.ContextMenu>\n                        <ContextMenu Style=\"{StaticResource DefContextMenu}\">\n                            <MenuItem\n                                x:Name=\"menuRuleAdd2\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Header=\"{x:Static resx:ResUI.menuRuleAdd}\" />\n                            <MenuItem\n                                x:Name=\"menuRuleRemove\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Header=\"{x:Static resx:ResUI.menuRuleRemove}\" />\n                            <MenuItem\n                                x:Name=\"menuRuleSelectAll\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Click=\"menuRuleSelectAll_Click\"\n                                Header=\"{x:Static resx:ResUI.menuSelectAll}\" />\n                            <MenuItem\n                                x:Name=\"menuRuleExportSelected\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Header=\"{x:Static resx:ResUI.menuRuleExportSelected}\" />\n                            <Separator />\n                            <MenuItem\n                                x:Name=\"menuMoveTop\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Header=\"{x:Static resx:ResUI.menuMoveTop}\" />\n                            <MenuItem\n                                x:Name=\"menuMoveUp\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Header=\"{x:Static resx:ResUI.menuMoveUp}\" />\n                            <MenuItem\n                                x:Name=\"menuMoveDown\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Header=\"{x:Static resx:ResUI.menuMoveDown}\" />\n                            <MenuItem\n                                x:Name=\"menuMoveBottom\"\n                                Height=\"{StaticResource MenuItemHeight}\"\n                                Header=\"{x:Static resx:ResUI.menuMoveBottom}\" />\n                        </ContextMenu>\n                    </DataGrid.ContextMenu>\n                    <DataGrid.Columns>\n                        <DataGridTextColumn\n                            Width=\"120\"\n                            Binding=\"{Binding outboundTag}\"\n                            Header=\"outboundTag\" />\n                        <DataGridTextColumn\n                            Width=\"100\"\n                            Binding=\"{Binding port}\"\n                            Header=\"port\" />\n                        <DataGridTextColumn\n                            Width=\"100\"\n                            Binding=\"{Binding protocols}\"\n                            Header=\"protocol\" />\n                        <DataGridTextColumn\n                            Width=\"120\"\n                            Binding=\"{Binding inboundTags}\"\n                            Header=\"inboundTag\" />\n                        <DataGridTextColumn\n                            Width=\"150\"\n                            Binding=\"{Binding domains}\"\n                            Header=\"domain\" />\n                        <DataGridTextColumn\n                            Width=\"150\"\n                            Binding=\"{Binding ips}\"\n                            Header=\"ip\" />\n                        <DataGridTextColumn\n                            Width=\"80\"\n                            Binding=\"{Binding enabled}\"\n                            Header=\"enabled\" />\n                    </DataGrid.Columns>\n                </DataGrid>\n            </TabItem>\n        </TabControl>\n    </DockPanel>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml.cs",
    "content": "﻿using Microsoft.Win32;\nusing ReactiveUI;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing System.Windows.Input;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class RoutingRuleSettingWindow\n    {\n        public RoutingRuleSettingWindow(RoutingItem routingItem)\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            this.Loaded += Window_Loaded;\n            this.PreviewKeyDown += RoutingRuleSettingWindow_PreviewKeyDown;\n            lstRules.SelectionChanged += lstRules_SelectionChanged;\n            lstRules.MouseDoubleClick += LstRules_MouseDoubleClick;\n\n            ViewModel = new RoutingRuleSettingViewModel(routingItem, this);\n            Global.domainStrategys.ForEach(it =>\n            {\n                cmbdomainStrategy.Items.Add(it);\n            });\n            cmbdomainStrategy.Items.Add(string.Empty);\n            Global.domainStrategys4Singbox.ForEach(it =>\n            {\n                cmbdomainStrategy4Singbox.Items.Add(it);\n            });\n\n            this.WhenActivated(disposables =>\n            {\n                this.OneWayBind(ViewModel, vm => vm.RulesItems, v => v.lstRules.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRules.SelectedItem).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.SelectedRouting.remarks, v => v.txtRemarks.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedRouting.domainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedRouting.domainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables);\n                \n                this.Bind(ViewModel, vm => vm.SelectedRouting.url, v => v.txtUrl.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedRouting.customIcon, v => v.txtCustomIcon.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedRouting.sort, v => v.txtSort.Text).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ImportRulesFromFileCmd, v => v.menuImportRulesFromFile).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ImportRulesFromClipboardCmd, v => v.menuImportRulesFromClipboard).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.ImportRulesFromUrlCmd, v => v.menuImportRulesFromUrl).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.RuleAddCmd, v => v.menuRuleAdd2).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RuleRemoveCmd, v => v.menuRuleRemove).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RuleExportSelectedCmd, v => v.menuRuleExportSelected).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.MoveTopCmd, v => v.menuMoveTop).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.MoveUpCmd, v => v.menuMoveUp).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.MoveDownCmd, v => v.menuMoveDown).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.MoveBottomCmd, v => v.menuMoveBottom).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);\n            });\n        }\n\n        private void Window_Loaded(object sender, RoutedEventArgs e)\n        {\n            txtRemarks.Focus();\n        }\n\n        private void RoutingRuleSettingWindow_PreviewKeyDown(object sender, KeyEventArgs e)\n        {\n            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))\n            {\n                if (e.Key == Key.A)\n                {\n                    lstRules.SelectAll();\n                }\n                else if (e.Key == Key.C)\n                {\n                    ViewModel?.RuleExportSelected();\n                }\n            }\n            else\n            {\n                if (e.Key == Key.T)\n                {\n                    ViewModel?.MoveRule(EMove.Top);\n                }\n                else if (e.Key == Key.U)\n                {\n                    ViewModel?.MoveRule(EMove.Up);\n                }\n                else if (e.Key == Key.D)\n                {\n                    ViewModel?.MoveRule(EMove.Down);\n                }\n                else if (e.Key == Key.B)\n                {\n                    ViewModel?.MoveRule(EMove.Bottom);\n                }\n                else if (e.Key == Key.Delete)\n                {\n                    ViewModel?.RuleRemove();\n                }\n            }\n        }\n\n        private void lstRules_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)\n        {\n            ViewModel.SelectedSources = lstRules.SelectedItems.Cast<RulesItemModel>().ToList();\n        }\n\n        private void LstRules_MouseDoubleClick(object sender, MouseButtonEventArgs e)\n        {\n            ViewModel?.RuleEdit(false);\n        }\n\n        private void menuRuleSelectAll_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            lstRules.SelectAll();\n        }\n\n        private void btnBrowse_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            var openFileDialog1 = new OpenFileDialog();\n            openFileDialog1.Filter = \"PNG|*.png\";\n            openFileDialog1.ShowDialog();\n\n            txtCustomIcon.Text = openFileDialog1.FileName;\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/RoutingSettingWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.RoutingSettingWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuRoutingSetting}\"\n    Width=\"990\"\n    Height=\"700\"\n    x:TypeArguments=\"vms:RoutingSettingViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <Window.Resources>\n        <ResourceDictionary>\n            <BooleanToVisibilityConverter x:Key=\"BoolToVisConverter\" />\n        </ResourceDictionary>\n    </Window.Resources>\n    <DockPanel>\n        <ToolBarTray DockPanel.Dock=\"Top\">\n            <ToolBar\n                HorizontalAlignment=\"Center\"\n                VerticalAlignment=\"Center\"\n                ClipToBounds=\"True\"\n                Style=\"{StaticResource MaterialDesignToolBar}\">\n                <Menu Margin=\"0,8\" Style=\"{StaticResource ToolbarMenu}\">\n                    <MenuItem x:Name=\"menuRoutingBasic\" Padding=\"8,0\">\n                        <MenuItem.Header>\n                            <StackPanel Orientation=\"Horizontal\">\n                                <materialDesign:PackIcon\n                                    Margin=\"0,0,8,0\"\n                                    VerticalAlignment=\"Center\"\n                                    Kind=\"Server\" />\n                                <TextBlock Text=\"{x:Static resx:ResUI.menuRoutingBasic}\" />\n                            </StackPanel>\n                        </MenuItem.Header>\n                        <MenuItem\n                            x:Name=\"menuRoutingBasicImportRules\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Header=\"{x:Static resx:ResUI.menuRoutingBasicImportRules}\" />\n                    </MenuItem>\n                </Menu>\n                <Menu Margin=\"0,8\" Style=\"{StaticResource ToolbarMenu}\">\n                    <MenuItem x:Name=\"menuRoutingAdvanced\" Padding=\"8,0\">\n                        <MenuItem.Header>\n                            <StackPanel Orientation=\"Horizontal\">\n                                <materialDesign:PackIcon\n                                    Margin=\"0,0,8,0\"\n                                    VerticalAlignment=\"Center\"\n                                    Kind=\"Routes\" />\n                                <TextBlock Text=\"{x:Static resx:ResUI.menuRoutingAdvanced}\" />\n                            </StackPanel>\n                        </MenuItem.Header>\n                        <MenuItem\n                            x:Name=\"menuRoutingAdvancedAdd2\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Header=\"{x:Static resx:ResUI.menuRoutingAdvancedAdd}\" />\n                        <MenuItem\n                            x:Name=\"menuRoutingAdvancedImportRules2\"\n                            Height=\"{StaticResource MenuItemHeight}\"\n                            Header=\"{x:Static resx:ResUI.menuRoutingAdvancedImportRules}\" />\n                    </MenuItem>\n                </Menu>\n                <Separator />\n                <TextBlock\n                    Margin=\"8,0,0,0\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbenableRoutingAdvanced}\" />\n                <ToggleButton\n                    x:Name=\"togenableRoutingAdvanced\"\n                    Margin=\"8,0,0,0\"\n                    HorizontalAlignment=\"Left\" />\n                <Separator />\n                <TextBlock\n                    Margin=\"8,0,0,0\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\">\n                    <Hyperlink Click=\"linkdomainStrategy_Click\">\n                        <TextBlock Text=\"{x:Static resx:ResUI.TbdomainStrategy}\" />\n                    </Hyperlink>\n                </TextBlock>\n                <ComboBox\n                    x:Name=\"cmbdomainStrategy\"\n                    Width=\"110\"\n                    Margin=\"8,0,0,0\"\n                    Style=\"{StaticResource DefComboBox}\" />\n                <Separator />\n                <TextBlock\n                    Margin=\"8,0,0,0\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.TbdomainMatcher}\" />\n                <ComboBox\n                    x:Name=\"cmbdomainMatcher\"\n                    Width=\"60\"\n                    Margin=\"8,0,0,0\"\n                    Style=\"{StaticResource DefComboBox}\" />\n                <Separator />\n                <TextBlock\n                    Margin=\"8,0,0,0\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\">\n                    <Hyperlink Click=\"linkdomainStrategy4Singbox_Click\">\n                        <TextBlock Text=\"{x:Static resx:ResUI.TbdomainStrategy4Singbox}\" />\n                    </Hyperlink>\n                </TextBlock>\n                <ComboBox\n                    x:Name=\"cmbdomainStrategy4Singbox\"\n                    Width=\"100\"\n                    Margin=\"8,0,0,0\"\n                    Style=\"{StaticResource DefComboBox}\" />\n            </ToolBar>\n        </ToolBarTray>\n\n        <Grid\n            Margin=\"8\"\n            HorizontalAlignment=\"Center\"\n            DockPanel.Dock=\"Bottom\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"600\" />\n                <ColumnDefinition Width=\"100\" />\n                <ColumnDefinition Width=\"100\" />\n            </Grid.ColumnDefinitions>\n            <StackPanel\n                Grid.Column=\"0\"\n                HorizontalAlignment=\"Left\"\n                VerticalAlignment=\"Center\">\n                <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.TbRoutingTips}\" />\n            </StackPanel>\n            <Button\n                x:Name=\"btnSave\"\n                Grid.Column=\"1\"\n                Margin=\"4\"\n                Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                Cursor=\"Hand\"\n                Style=\"{StaticResource DefButton}\" />\n            <Button\n                x:Name=\"btnCancel\"\n                Grid.Column=\"2\"\n                Margin=\"4\"\n                Click=\"btnCancel_Click\"\n                Content=\"{x:Static resx:ResUI.TbCancel}\"\n                Cursor=\"Hand\"\n                IsCancel=\"true\"\n                Style=\"{StaticResource DefButton}\" />\n        </Grid>\n\n        <DockPanel>\n            <TabControl x:Name=\"tabAdvanced\">\n                <TabItem HorizontalAlignment=\"Left\" Header=\"{x:Static resx:ResUI.TbRoutingTabRuleList}\">\n                    <DataGrid\n                        x:Name=\"lstRoutings\"\n                        Margin=\"2,0\"\n                        AutoGenerateColumns=\"False\"\n                        BorderThickness=\"1\"\n                        CanUserAddRows=\"False\"\n                        CanUserResizeRows=\"False\"\n                        CanUserSortColumns=\"False\"\n                        EnableRowVirtualization=\"True\"\n                        GridLinesVisibility=\"All\"\n                        HeadersVisibility=\"Column\"\n                        IsReadOnly=\"True\"\n                        Style=\"{StaticResource DefDataGrid}\">\n                        <DataGrid.ContextMenu>\n                            <ContextMenu Style=\"{StaticResource DefContextMenu}\">\n                                <MenuItem\n                                    x:Name=\"menuRoutingAdvancedAdd\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRoutingAdvancedAdd}\" />\n                                <MenuItem\n                                    x:Name=\"menuRoutingAdvancedRemove\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRoutingAdvancedRemove}\" />\n                                <MenuItem\n                                    x:Name=\"menuRoutingAdvancedSelectAll\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Click=\"menuRoutingAdvancedSelectAll_Click\"\n                                    Header=\"{x:Static resx:ResUI.menuSelectAll}\" />\n                                <MenuItem\n                                    x:Name=\"menuRoutingAdvancedSetDefault\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRoutingAdvancedSetDefault}\" />\n                                <Separator />\n                                <MenuItem\n                                    x:Name=\"menuRoutingAdvancedImportRules\"\n                                    Height=\"{StaticResource MenuItemHeight}\"\n                                    Header=\"{x:Static resx:ResUI.menuRoutingAdvancedImportRules}\" />\n                            </ContextMenu>\n                        </DataGrid.ContextMenu>\n                        <DataGrid.Resources>\n                            <Style BasedOn=\"{StaticResource MaterialDesignDataGridCell}\" TargetType=\"DataGridCell\">\n                                <Style.Triggers>\n                                    <DataTrigger Binding=\"{Binding isActive}\" Value=\"True\">\n                                        <Setter Property=\"Background\" Value=\"{DynamicResource PrimaryHueLightBrush}\" />\n                                        <Setter Property=\"Foreground\" Value=\"Black\" />\n                                        <Setter Property=\"BorderBrush\" Value=\"{DynamicResource PrimaryHueLightBrush}\" />\n                                    </DataTrigger>\n                                </Style.Triggers>\n                            </Style>\n                        </DataGrid.Resources>\n                        <DataGrid.Columns>\n                            <DataGridTextColumn\n                                Width=\"250\"\n                                Binding=\"{Binding remarks}\"\n                                Header=\"{x:Static resx:ResUI.LvRemarks}\" />\n                            <DataGridTextColumn\n                                Width=\"60\"\n                                Binding=\"{Binding ruleNum}\"\n                                Header=\"{x:Static resx:ResUI.LvCount}\" />\n                            <DataGridTextColumn\n                                Width=\"60\"\n                                Binding=\"{Binding sort}\"\n                                Header=\"{x:Static resx:ResUI.LvSort}\" />\n                            <DataGridTextColumn\n                                Width=\"300\"\n                                Binding=\"{Binding url}\"\n                                Header=\"{x:Static resx:ResUI.LvUrl}\" />\n                            <DataGridTextColumn\n                                Width=\"300\"\n                                Binding=\"{Binding customIcon}\"\n                                Header=\"{x:Static resx:ResUI.LvCustomIcon}\" />\n                        </DataGrid.Columns>\n                    </DataGrid>\n                </TabItem>\n            </TabControl>\n\n            <TabControl x:Name=\"tabBasic\">\n                <TabItem Header=\"{x:Static resx:ResUI.TbRoutingTabProxy}\">\n                    <Grid Margin=\"{StaticResource SettingItemMargin}\">\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"1*\" />\n                            <ColumnDefinition Width=\"10\" />\n                            <ColumnDefinition Width=\"1*\" />\n                        </Grid.ColumnDefinitions>\n                        <GroupBox\n                            Grid.Column=\"0\"\n                            Header=\"Domain\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtProxyDomain\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                        <GridSplitter Grid.Column=\"1\" HorizontalAlignment=\"Stretch\" />\n                        <GroupBox\n                            Grid.Column=\"2\"\n                            Header=\"IP\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtProxyIP\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                    </Grid>\n                </TabItem>\n\n                <TabItem Header=\"{x:Static resx:ResUI.TbRoutingTabDirect}\">\n                    <Grid Margin=\"{StaticResource SettingItemMargin}\">\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"1*\" />\n                            <ColumnDefinition Width=\"10\" />\n                            <ColumnDefinition Width=\"1*\" />\n                        </Grid.ColumnDefinitions>\n                        <GroupBox\n                            Grid.Column=\"0\"\n                            Header=\"Domain\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtDirectDomain\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                        <GridSplitter Grid.Column=\"1\" HorizontalAlignment=\"Stretch\" />\n                        <GroupBox\n                            Grid.Column=\"2\"\n                            Header=\"IP\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtDirectIP\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                    </Grid>\n                </TabItem>\n\n                <TabItem Header=\"{x:Static resx:ResUI.TbRoutingTabBlock}\">\n                    <Grid Margin=\"{StaticResource SettingItemMargin}\">\n                        <Grid.ColumnDefinitions>\n                            <ColumnDefinition Width=\"1*\" />\n                            <ColumnDefinition Width=\"10\" />\n                            <ColumnDefinition Width=\"1*\" />\n                        </Grid.ColumnDefinitions>\n                        <GroupBox\n                            Grid.Column=\"0\"\n                            Header=\"Domain\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtBlockDomain\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                        <GridSplitter Grid.Column=\"1\" HorizontalAlignment=\"Stretch\" />\n                        <GroupBox\n                            Grid.Column=\"2\"\n                            Header=\"IP\"\n                            Style=\"{StaticResource MyGroupBox}\">\n                            <TextBox\n                                Name=\"txtBlockIP\"\n                                AcceptsReturn=\"True\"\n                                Style=\"{StaticResource DefTextBox}\"\n                                TextWrapping=\"Wrap\"\n                                VerticalScrollBarVisibility=\"Auto\" />\n                        </GroupBox>\n                    </Grid>\n                </TabItem>\n            </TabControl>\n        </DockPanel>\n    </DockPanel>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs",
    "content": "﻿using ReactiveUI;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing System.Windows.Input;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class RoutingSettingWindow\n    {\n        public RoutingSettingWindow()\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            this.Closing += RoutingSettingWindow_Closing;\n            this.PreviewKeyDown += RoutingSettingWindow_PreviewKeyDown;\n            lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;\n            lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;\n\n            ViewModel = new RoutingSettingViewModel(this);\n\n            Global.domainStrategys.ForEach(it =>\n            {\n                cmbdomainStrategy.Items.Add(it);\n            });\n            Global.domainMatchers.ForEach(it =>\n            {\n                cmbdomainMatcher.Items.Add(it);\n            });\n            Global.domainStrategys4Singbox.ForEach(it =>\n            {\n                cmbdomainStrategy4Singbox.Items.Add(it);\n            });\n\n            this.WhenActivated(disposables =>\n            {\n                this.OneWayBind(ViewModel, vm => vm.RoutingItems, v => v.lstRoutings.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstRoutings.SelectedItem).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.enableRoutingAdvanced, v => v.togenableRoutingAdvanced.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.domainStrategy, v => v.cmbdomainStrategy.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.domainMatcher, v => v.cmbdomainMatcher.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.domainStrategy4Singbox, v => v.cmbdomainStrategy4Singbox.Text).DisposeWith(disposables);\n\n                this.Bind(ViewModel, vm => vm.ProxyDomain, v => v.txtProxyDomain.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.ProxyIP, v => v.txtProxyIP.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.DirectDomain, v => v.txtDirectDomain.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.DirectIP, v => v.txtDirectIP.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.BlockDomain, v => v.txtBlockDomain.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.BlockIP, v => v.txtBlockIP.Text).DisposeWith(disposables);\n\n                this.OneWayBind(ViewModel, vm => vm.enableRoutingBasic, v => v.menuRoutingBasic.Visibility).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.enableRoutingAdvanced, v => v.menuRoutingAdvanced.Visibility).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.enableRoutingBasic, v => v.tabBasic.Visibility).DisposeWith(disposables);\n                this.OneWayBind(ViewModel, vm => vm.enableRoutingAdvanced, v => v.tabAdvanced.Visibility).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.RoutingBasicImportRulesCmd, v => v.menuRoutingBasicImportRules).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RoutingAdvancedAddCmd, v => v.menuRoutingAdvancedAdd2).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RoutingAdvancedRemoveCmd, v => v.menuRoutingAdvancedRemove).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RoutingAdvancedSetDefaultCmd, v => v.menuRoutingAdvancedSetDefault).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.RoutingAdvancedImportRulesCmd, v => v.menuRoutingAdvancedImportRules2).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);\n            });\n        }\n\n        private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)\n        {\n            if (ViewModel?.IsModified == true)\n            {\n                this.DialogResult = true;\n            }\n        }\n\n        private void RoutingSettingWindow_PreviewKeyDown(object sender, KeyEventArgs e)\n        {\n            if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))\n            {\n                if (e.Key == Key.A)\n                {\n                    lstRoutings.SelectAll();\n                }\n            }\n            else if (e.Key is Key.Enter or Key.Return)\n            {\n                ViewModel?.RoutingAdvancedSetDefault();\n            }\n            else if (e.Key == Key.Delete)\n            {\n                ViewModel?.RoutingAdvancedRemove();\n            }\n        }\n\n        private void menuRoutingAdvancedSelectAll_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            lstRoutings.SelectAll();\n        }\n\n        private void lstRoutings_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)\n        {\n            ViewModel.SelectedSources = lstRoutings.SelectedItems.Cast<RoutingItemModel>().ToList();\n        }\n\n        private void LstRoutings_MouseDoubleClick(object sender, MouseButtonEventArgs e)\n        {\n            ViewModel?.RoutingAdvancedEdit(false);\n        }\n\n        private void linkdomainStrategy_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            Utils.ProcessStart(\"https://www.v2fly.org/config/routing.html\");\n        }\n\n        private void linkdomainStrategy4Singbox_Click(object sender, RoutedEventArgs e)\n        {\n            Utils.ProcessStart(\"https://sing-box.sagernet.org/zh/configuration/shared/listen/#domain_strategy\");\n        }\n\n        private void btnCancel_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            if (ViewModel?.IsModified == true)\n            {\n                this.DialogResult = true;\n            }\n            else\n            {\n                this.Close();\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/SubEditWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.SubEditWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuSubSetting}\"\n    Width=\"700\"\n    Height=\"600\"\n    x:TypeArguments=\"vms:SubEditViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <Window.Resources>\n        <ResourceDictionary>\n            <ResourceDictionary.MergedDictionaries>\n                <ResourceDictionary Source=\"pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml\" />\n            </ResourceDictionary.MergedDictionaries>\n        </ResourceDictionary>\n    </Window.Resources>\n\n    <ScrollViewer\n        materialDesign:ScrollViewerAssist.IsAutoHideEnabled=\"True\"\n        HorizontalScrollBarVisibility=\"Auto\"\n        VerticalScrollBarVisibility=\"Auto\">\n        <Grid Margin=\"8\">\n            <Grid.RowDefinitions>\n                <RowDefinition Height=\"Auto\" />\n                <RowDefinition Height=\"Auto\" />\n            </Grid.RowDefinitions>\n            <Grid Grid.Row=\"0\">\n                <Grid.RowDefinitions>\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                    <RowDefinition Height=\"Auto\" />\n                </Grid.RowDefinitions>\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                    <ColumnDefinition Width=\"Auto\" />\n                </Grid.ColumnDefinitions>\n\n                <TextBlock\n                    Grid.Row=\"0\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    Style=\"{StaticResource ModuleTitle}\"\n                    Text=\"{x:Static resx:ResUI.menuSubscription}\" />\n\n                <TextBlock\n                    Grid.Row=\"1\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.LvRemarks}\" />\n\n                <TextBox\n                    x:Name=\"txtRemarks\"\n                    Grid.Row=\"1\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\"\n                    TextWrapping=\"Wrap\" />\n\n                <TextBlock\n                    Grid.Row=\"2\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.LvUrl}\" />\n                <TextBox\n                    x:Name=\"txtUrl\"\n                    Grid.Row=\"2\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.SubUrlTips}\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\"\n                    TextWrapping=\"Wrap\" />\n\n                <materialDesign:PopupBox\n                    Grid.Row=\"2\"\n                    Grid.Column=\"2\"\n                    HorizontalAlignment=\"Right\"\n                    StaysOpen=\"True\"\n                    Style=\"{StaticResource MaterialDesignToolForegroundPopupBox}\">\n                    <StackPanel>\n                        <TextBlock\n                            Margin=\"4\"\n                            VerticalAlignment=\"Center\"\n                            Style=\"{StaticResource ToolbarTextBlock}\"\n                            Text=\"{x:Static resx:ResUI.LvMoreUrl}\" />\n                        <TextBox\n                            x:Name=\"txtMoreUrl\"\n                            Width=\"400\"\n                            Margin=\"4\"\n                            VerticalAlignment=\"Top\"\n                            materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.SubUrlTips}\"\n                            AcceptsReturn=\"True\"\n                            MinLines=\"4\"\n                            Style=\"{StaticResource MyOutlinedTextBox}\"\n                            TextWrapping=\"Wrap\" />\n                    </StackPanel>\n                </materialDesign:PopupBox>\n\n                <TextBlock\n                    Grid.Row=\"3\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.LvEnabled}\" />\n                <ToggleButton\n                    x:Name=\"togEnable\"\n                    Grid.Row=\"3\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    HorizontalAlignment=\"Left\" />\n\n                <TextBlock\n                    Grid.Row=\"4\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.LvAutoUpdateInterval}\" />\n                <TextBox\n                    x:Name=\"txtAutoUpdateInterval\"\n                    Grid.Row=\"4\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.SubUrlTips}\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n\n                <TextBlock\n                    Grid.Row=\"5\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Text=\"{x:Static resx:ResUI.LvUserAgent}\" />\n                <TextBox\n                    x:Name=\"txtUserAgent\"\n                    Grid.Row=\"5\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.SubUrlTips}\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\"\n                    TextWrapping=\"Wrap\" />\n\n                <TextBlock\n                    Grid.Row=\"6\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.LvFilter}\" />\n                <TextBox\n                    x:Name=\"txtFilter\"\n                    Grid.Row=\"6\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.SubUrlTips}\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n\n\n                <TextBlock\n                    Grid.Row=\"7\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.LvConvertTarget}\" />\n                <ComboBox\n                    x:Name=\"cmbConvertTarget\"\n                    Grid.Row=\"7\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    materialDesign:HintAssist.Hint=\"{x:Static resx:ResUI.LvConvertTargetTip}\"\n                    FontSize=\"{DynamicResource StdFontSize}\"\n                    MaxDropDownHeight=\"1000\"\n                    Style=\"{StaticResource MaterialDesignOutlinedComboBox}\" />\n\n\n                <TextBlock\n                    Grid.Row=\"8\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Center\"\n                    Style=\"{StaticResource ToolbarTextBlock}\"\n                    Text=\"{x:Static resx:ResUI.LvSort}\" />\n                <TextBox\n                    x:Name=\"txtSort\"\n                    Grid.Row=\"8\"\n                    Grid.Column=\"1\"\n                    Width=\"400\"\n                    Margin=\"4\"\n                    VerticalAlignment=\"Top\"\n                    AcceptsReturn=\"True\"\n                    Style=\"{StaticResource MyOutlinedTextBox}\" />\n            </Grid>\n            <Grid\n                Grid.Row=\"1\"\n                Margin=\"8\"\n                HorizontalAlignment=\"Center\">\n                <Grid.ColumnDefinitions>\n                    <ColumnDefinition Width=\"200\" />\n                    <ColumnDefinition Width=\"200\" />\n                </Grid.ColumnDefinitions>\n                <Button\n                    x:Name=\"btnSave\"\n                    Grid.Column=\"0\"\n                    Margin=\"4\"\n                    Content=\"{x:Static resx:ResUI.TbConfirm}\"\n                    Cursor=\"Hand\"\n                    Style=\"{StaticResource DefButton}\" />\n                <Button\n                    x:Name=\"btnCancel\"\n                    Grid.Column=\"1\"\n                    Margin=\"4\"\n                    Click=\"btnCancel_Click\"\n                    Content=\"{x:Static resx:ResUI.TbCancel}\"\n                    Cursor=\"Hand\"\n                    IsCancel=\"true\"\n                    Style=\"{StaticResource DefButton}\" />\n            </Grid>\n        </Grid>\n    </ScrollViewer>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/SubEditWindow.xaml.cs",
    "content": "﻿using ReactiveUI;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class SubEditWindow\n    {\n        public SubEditWindow(SubItem subItem)\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n            this.Loaded += Window_Loaded;\n\n            ViewModel = new SubEditViewModel(subItem, this);\n\n            Global.SubConvertTargets.ForEach(it =>\n            {\n                cmbConvertTarget.Items.Add(it);\n            });\n\n            this.WhenActivated(disposables =>\n            {\n                this.Bind(ViewModel, vm => vm.SelectedSource.remarks, v => v.txtRemarks.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.url, v => v.txtUrl.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.moreUrl, v => v.txtMoreUrl.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.enabled, v => v.togEnable.IsChecked).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.profileUpdateInterval, v => v.txtAutoUpdateInterval.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.userAgent, v => v.txtUserAgent.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.sort, v => v.txtSort.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.filter, v => v.txtFilter.Text).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource.convertTarget, v => v.cmbConvertTarget.Text).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SaveCmd, v => v.btnSave).DisposeWith(disposables);\n            });\n        }\n\n        private void Window_Loaded(object sender, RoutedEventArgs e)\n        {\n            txtRemarks.Focus();\n        }\n\n        private void btnCancel_Click(object sender, RoutedEventArgs e)\n        {\n            this.Close();\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/Views/SubInfoView.xaml",
    "content": "﻿<UserControl x:Class=\"v2rayN.Views.SubInfoView\"\n             xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n                 xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n             xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n             xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n             xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\" \n             xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\" \n             xmlns:local=\"clr-namespace:v2rayN.Views\"\n             mc:Ignorable=\"d\" \n             d:DesignHeight=\"450\" d:DesignWidth=\"800\">\n    <UserControl.Resources>\n        <ResourceDictionary>\n            <ResourceDictionary.MergedDictionaries>\n                <ResourceDictionary Source=\"pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Popupbox.xaml\" />\n            </ResourceDictionary.MergedDictionaries>\n            <BooleanToVisibilityConverter x:Key=\"BoolToVisConverter\" />\n            <conv:DelayColorConverter x:Key=\"DelayColorConverter\" />\n            <conv:SizeConverter x:Key=\"SizeConverter\" />\n\n        </ResourceDictionary>\n    </UserControl.Resources>\n    \n    <StackPanel  HorizontalAlignment=\"Stretch\" >\n        <Grid>\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"*\" />\n                <ColumnDefinition Width=\"auto\" />\n            </Grid.ColumnDefinitions>\n            <StackPanel Orientation=\"Horizontal\">\n                <TextBlock  \n                    VerticalAlignment=\"Center\" \n                    TextTrimming=\"CharacterEllipsis\" \n                    HorizontalAlignment=\"Stretch\"\n                    Style=\"{StaticResource MaterialDesignHeadline5TextBlock}\"\n                    Text=\"{Binding remarks}\" >\n\n                </TextBlock>\n                \n                <!--<Button Name=\"GotoProfile\"\n                    Command=\"{Binding HomeGotoProfileCmd}\"\n                    Margin=\"10,0,0,0\" Background=\"{x:Null}\" BorderBrush=\"{x:Null}\"\n                    Foreground=\"Black\"\n                    >\n                    <materialDesign:PackIcon Kind=\"OpenInNew\"  />\n                </Button>-->\n            </StackPanel>\n            \n                <!--<StackPanel Orientation=\"Horizontal\" >\n                    <materialDesign:PackIcon Kind=\"Plus\" VerticalAlignment=\"Center\"  />\n                    <TextBlock Style=\"{StaticResource MaterialDesignBody1TextBlock}\" >\n                                    New\n                    </TextBlock>\n\n                </StackPanel>-->\n           \n        </Grid>\n\n\n        <Grid Visibility=\"{Binding sub_info_visible}\">\n            <Grid.ColumnDefinitions>\n                <ColumnDefinition Width=\"auto\" />\n                <ColumnDefinition Width=\"*\" />\n            </Grid.ColumnDefinitions>\n\n            <StackPanel Margin=\"0,0,20,0\" Visibility=\"{Binding sub_info_visible}\">\n                <TextBlock HorizontalAlignment=\"Center\" Style=\"{StaticResource MaterialDesignBody1TextBlock}\" Text=\"{Binding remaningExpireDays,StringFormat={}{0} Days}\"></TextBlock>\n                <Label HorizontalAlignment=\"Center\">Remaining</Label>\n            </StackPanel>\n\n            <StackPanel Grid.Column=\"1\" Visibility=\"{Binding sub_info_visible}\">\n\n                <Grid >\n                    <Grid.ColumnDefinitions>\n                        <ColumnDefinition Width=\"auto\" />\n                        <ColumnDefinition Width=\"*\" />\n                    </Grid.ColumnDefinitions>\n\n\n                    <!--<Button Name=\"UpdateUsage\" Grid.Column=\"0\" HorizontalAlignment=\"Left\"\n                                                VerticalAlignment=\"Bottom\"  Padding=\"0\" materialDesign:ButtonAssist.CornerRadius=\"8\" \n                                                Background=\"{x:Null}\"\n                                                Command=\"{Binding HomeUpdateUsageCmd}\"\n                                                BorderBrush=\"{x:Null}\" Foreground=\"#FF0E0808\">\n                        <StackPanel Orientation=\"Horizontal\" >\n                            <TextBlock  >\n                                    Usage\n                            </TextBlock>\n                            <materialDesign:PackIcon Kind=\"Refresh\" VerticalAlignment=\"Center\"  />\n\n                        </StackPanel>\n                    </Button>-->\n\n                    <Label Grid.Column=\"1\" HorizontalAlignment=\"Right\" VerticalAlignment=\"Bottom\">\n                        <Label.Content >\n                            <TextBlock>\n                                <TextBlock.Text>\n                                    <MultiBinding StringFormat=\"{}{0}/{1}\">\n                                        <Binding Path=\"usage\" Converter=\"{StaticResource SizeConverter}\"/>\n                                        <Binding Path=\"total\" Converter=\"{StaticResource SizeConverter}\"/>\n                                    </MultiBinding>\n                                </TextBlock.Text>\n                            </TextBlock>\n                        </Label.Content>\n                    </Label>\n                </Grid>\n                <!--TODO: @hiddify1; Fix this progress bar-->\n                <ProgressBar Height=\"10\" Value=\"{Binding usage}\" Maximum=\"{Binding total}\" HorizontalAlignment=\"Stretch\" />\n            </StackPanel>\n        </Grid>\n    </StackPanel>\n</UserControl>\n"
  },
  {
    "path": "v2rayN/v2rayN/Views/SubInfoView.xaml.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing System.Windows;\nusing System.Windows.Controls;\nusing System.Windows.Data;\nusing System.Windows.Documents;\nusing System.Windows.Input;\nusing System.Windows.Media;\nusing System.Windows.Media.Imaging;\nusing System.Windows.Navigation;\nusing System.Windows.Shapes;\n\nnamespace v2rayN.Views\n{\n    /// <summary>\n    /// Interaction logic for SubInfoView.xaml\n    /// </summary>\n    public partial class SubInfoView : UserControl\n    {\n        public SubInfoView()\n        {\n            InitializeComponent();\n        }\n    }\n}\n"
  },
  {
    "path": "v2rayN/v2rayN/Views/SubSettingWindow.xaml",
    "content": "﻿<reactiveui:ReactiveWindow\n    x:Class=\"v2rayN.Views.SubSettingWindow\"\n    xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"\n    xmlns:x=\"http://schemas.microsoft.com/winfx/2006/xaml\"\n    xmlns:conv=\"clr-namespace:v2rayN.Converters\"\n    xmlns:d=\"http://schemas.microsoft.com/expression/blend/2008\"\n    xmlns:materialDesign=\"http://materialdesigninxaml.net/winfx/xaml/themes\"\n    xmlns:mc=\"http://schemas.openxmlformats.org/markup-compatibility/2006\"\n    xmlns:reactiveui=\"http://reactiveui.net\"\n    xmlns:resx=\"clr-namespace:v2rayN.Resx\"\n    xmlns:vms=\"clr-namespace:v2rayN.ViewModels\"\n    Title=\"{x:Static resx:ResUI.menuSubSetting}\"\n    Width=\"800\"\n    Height=\"600\"\n    x:TypeArguments=\"vms:SubSettingViewModel\"\n    Background=\"{DynamicResource MaterialDesignPaper}\"\n    FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    ResizeMode=\"NoResize\"\n    ShowInTaskbar=\"False\"\n    TextElement.FontFamily=\"{x:Static conv:MaterialDesignFonts.MyFont}\"\n    TextElement.Foreground=\"{DynamicResource MaterialDesignBody}\"\n    TextOptions.TextFormattingMode=\"Display\"\n    TextOptions.TextRenderingMode=\"Auto\"\n    WindowStartupLocation=\"CenterScreen\"\n    mc:Ignorable=\"d\">\n    <materialDesign:DialogHost Identifier=\"SubDialog\" Style=\"{StaticResource MaterialDesignEmbeddedDialogHost}\">\n        <DockPanel>\n            <ToolBarTray DockPanel.Dock=\"Top\">\n                <ToolBar\n                    HorizontalAlignment=\"Center\"\n                    VerticalAlignment=\"Center\"\n                    ClipToBounds=\"True\"\n                    Style=\"{StaticResource MaterialDesignToolBar}\">\n                    <Button x:Name=\"menuSubAdd\">\n                        <StackPanel Orientation=\"Horizontal\">\n                            <materialDesign:PackIcon\n                                Margin=\"0,0,8,0\"\n                                VerticalAlignment=\"Center\"\n                                Kind=\"Plus\" />\n                            <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuSubAdd}\" />\n                        </StackPanel>\n                    </Button>\n                    <Separator />\n                    <Button x:Name=\"menuSubDelete\">\n                        <StackPanel Orientation=\"Horizontal\">\n                            <materialDesign:PackIcon\n                                Margin=\"0,0,8,0\"\n                                VerticalAlignment=\"Center\"\n                                Kind=\"Delete\" />\n                            <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuSubDelete}\" />\n                        </StackPanel>\n                    </Button>\n                    <Separator />\n                    <Button x:Name=\"menuSubEdit\">\n                        <StackPanel Orientation=\"Horizontal\">\n                            <materialDesign:PackIcon\n                                Margin=\"0,0,8,0\"\n                                VerticalAlignment=\"Center\"\n                                Kind=\"Edit\" />\n                            <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuSubEdit}\" />\n                        </StackPanel>\n                    </Button>\n                    <Separator />\n                    <Button x:Name=\"menuSubShare\">\n                        <StackPanel Orientation=\"Horizontal\">\n                            <materialDesign:PackIcon\n                                Margin=\"0,0,8,0\"\n                                VerticalAlignment=\"Center\"\n                                Kind=\"QrcodePlus\" />\n                            <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuSubShare}\" />\n                        </StackPanel>\n                    </Button>\n                    <Button\n                        x:Name=\"menuClose\"\n                        Click=\"menuClose_Click\"\n                        IsCancel=\"True\">\n                        <StackPanel Orientation=\"Horizontal\">\n                            <materialDesign:PackIcon\n                                Margin=\"0,0,8,0\"\n                                VerticalAlignment=\"Center\"\n                                Kind=\"Close\" />\n                            <TextBlock Style=\"{StaticResource ToolbarTextBlock}\" Text=\"{x:Static resx:ResUI.menuClose}\" />\n                        </StackPanel>\n                    </Button>\n                </ToolBar>\n            </ToolBarTray>\n\n            <DataGrid\n                x:Name=\"lstSubscription\"\n                AutoGenerateColumns=\"False\"\n                BorderThickness=\"1\"\n                CanUserAddRows=\"False\"\n                CanUserResizeRows=\"False\"\n                CanUserSortColumns=\"False\"\n                EnableRowVirtualization=\"True\"\n                GridLinesVisibility=\"All\"\n                HeadersVisibility=\"Column\"\n                IsReadOnly=\"True\"\n                Style=\"{StaticResource DefDataGrid}\">\n                <DataGrid.Columns>\n                    <DataGridTextColumn\n                        Width=\"120\"\n                        Binding=\"{Binding remarks}\"\n                        Header=\"{x:Static resx:ResUI.LvRemarks}\" />\n                    <DataGridTextColumn\n                        Width=\"150\"\n                        Binding=\"{Binding url}\"\n                        Header=\"{x:Static resx:ResUI.LvUrl}\" />\n                    <DataGridTextColumn\n                        Width=\"100\"\n                        Binding=\"{Binding enabled}\"\n                        Header=\"{x:Static resx:ResUI.LvEnabled}\" />\n                    <DataGridTextColumn\n                        Width=\"150\"\n                        Binding=\"{Binding autoUpdateInterval}\"\n                        Header=\"{x:Static resx:ResUI.LvAutoUpdateInterval}\" />\n                    <DataGridTextColumn\n                        Width=\"150\"\n                        Binding=\"{Binding userAgent}\"\n                        Header=\"{x:Static resx:ResUI.LvUserAgent}\" />\n                    <DataGridTextColumn\n                        Width=\"80\"\n                        Binding=\"{Binding sort}\"\n                        Header=\"{x:Static resx:ResUI.LvSort}\" />\n                </DataGrid.Columns>\n            </DataGrid>\n        </DockPanel>\n    </materialDesign:DialogHost>\n</reactiveui:ReactiveWindow>"
  },
  {
    "path": "v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs",
    "content": "﻿using ReactiveUI;\nusing System.ComponentModel;\nusing System.Reactive.Disposables;\nusing System.Windows;\nusing System.Windows.Input;\nusing v2rayN.Mode;\nusing v2rayN.ViewModels;\n\nnamespace v2rayN.Views\n{\n    public partial class SubSettingWindow\n    {\n        public SubSettingWindow()\n        {\n            InitializeComponent();\n            this.Owner = Application.Current.MainWindow;\n\n            ViewModel = new SubSettingViewModel(this);\n            this.Closing += SubSettingWindow_Closing;\n            lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick;\n            lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;\n\n            this.WhenActivated(disposables =>\n            {\n                this.OneWayBind(ViewModel, vm => vm.SubItems, v => v.lstSubscription.ItemsSource).DisposeWith(disposables);\n                this.Bind(ViewModel, vm => vm.SelectedSource, v => v.lstSubscription.SelectedItem).DisposeWith(disposables);\n\n                this.BindCommand(ViewModel, vm => vm.SubAddCmd, v => v.menuSubAdd).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SubDeleteCmd, v => v.menuSubDelete).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SubEditCmd, v => v.menuSubEdit).DisposeWith(disposables);\n                this.BindCommand(ViewModel, vm => vm.SubShareCmd, v => v.menuSubShare).DisposeWith(disposables);\n            });\n        }\n\n        private void SubSettingWindow_Closing(object? sender, CancelEventArgs e)\n        {\n            if (ViewModel?.IsModified == true)\n            {\n                this.DialogResult = true;\n            }\n        }\n\n        private void LstSubscription_MouseDoubleClick(object sender, MouseButtonEventArgs e)\n        {\n            ViewModel?.EditSub(false);\n        }\n\n        private void LstSubscription_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)\n        {\n            ViewModel.SelectedSources = lstSubscription.SelectedItems.Cast<SubItem>().ToList();\n        }\n\n        private void menuClose_Click(object sender, System.Windows.RoutedEventArgs e)\n        {\n            if (ViewModel?.IsModified == true)\n            {\n                this.DialogResult = true;\n            }\n            else\n            {\n                this.Close();\n            }\n        }\n    }\n}"
  },
  {
    "path": "v2rayN/v2rayN/app.manifest",
    "content": "﻿<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\" xmlns:asmv3=\"urn:schemas-microsoft-com:asm.v3\">\n  <asmv3:application>\n    <asmv3:windowsSettings>\n      <dpiAware xmlns=\"http://schemas.microsoft.com/SMI/2005/WindowsSettings\">true</dpiAware>\n      <dpiAwareness xmlns=\"http://schemas.microsoft.com/SMI/2016/WindowsSettings\">PerMonitorV2</dpiAwareness>\n    </asmv3:windowsSettings>\n  </asmv3:application>\n\t\n\t<!-- Enable themes for Windows common controls and dialogs (Windows XP and later) -->\n\t<dependency>\n\t\t<dependentAssembly>\n\t\t\t<assemblyIdentity\n\t\t\t\ttype=\"win32\"\n\t\t\t\tname=\"Microsoft.Windows.Common-Controls\"\n\t\t\t\tversion=\"6.0.0.0\"\n\t\t\t\tprocessorArchitecture=\"*\"\n\t\t\t\tpublicKeyToken=\"6595b64144ccf1df\"\n\t\t\t\tlanguage=\"*\"\n        />\n\t\t</dependentAssembly>\n\t</dependency>\n\t<!--<trustInfo xmlns=\"urn:schemas-microsoft-com:asm.v3\">\n\t\t<security>\n\t\t  <requestedPrivileges>\n\t\t\t  <requestedExecutionLevel level=\"requireAdministrator\" uiAccess=\"false\" />\n\t\t  </requestedPrivileges>\n\t\t</security>\n\t</trustInfo>-->\n</assembly>"
  },
  {
    "path": "v2rayN/v2rayN/v2rayN.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk\">\n\n\t<PropertyGroup>\n\t\t<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>\n\t\t<OutputType>WinExe</OutputType>\n\t\t<TargetFramework>net6.0-windows</TargetFramework>\n\t\t<Nullable>enable</Nullable>\n\t\t<UseWPF>true</UseWPF>  \n\t\t<ApplicationManifest>app.manifest</ApplicationManifest>\n\t\t<ImplicitUsings>enable</ImplicitUsings>\n\t\t<ApplicationIcon>v2rayN.ico</ApplicationIcon>\n\t\t<Copyright>Copyright © 2017-2023 (GPLv3)</Copyright>\n\t\t<FileVersion>6.23</FileVersion>\n\t\t<AssemblyName>HiddifyN</AssemblyName>\n\t</PropertyGroup>\n\n\t<ItemGroup>\n\t\t<PackageReference Include=\"Downloader\" Version=\"3.0.4\" />\t\t\n\t\t<PackageReference Include=\"MaterialDesignThemes\" Version=\"4.7.1\" />\n\t\t<PackageReference Include=\"H.NotifyIcon.Wpf\" Version=\"2.0.108\" />\n\t\t<PackageReference Include=\"Newtonsoft.Json\" Version=\"13.0.3\" />\n\t\t<PackageReference Include=\"QRCoder.Xaml\" Version=\"1.4.3\" />\n\t\t<PackageReference Include=\"ReactiveUI.Validation\" Version=\"3.1.7\" />\n\t\t<PackageReference Include=\"sqlite-net-pcl\" Version=\"1.8.116\" />\n\t\t<PackageReference Include=\"System.Reactive\" Version=\"5.0.0\" />\n\t\t<PackageReference Include=\"TaskScheduler\" Version=\"2.10.1\" /> \n\t\t<PackageReference Include=\"ZXing.Net.Bindings.Windows.Compatibility\" Version=\"0.16.12\" />\n\t\t<PackageReference Include=\"ReactiveUI.Fody\" Version=\"18.4.26\" />\n\t\t<PackageReference Include=\"ReactiveUI.WPF\" Version=\"18.4.26\" />\n\t\t<PackageReference Include=\"Splat.NLog\" Version=\"14.6.8\" />\n\t</ItemGroup>\n\t\n\t<ItemGroup>       \n        <AdditionalFiles Include=\"app.manifest\" />       \n        <EmbeddedResource Include=\"Sample\\SingboxSampleClientConfig\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>       \n        <EmbeddedResource Include=\"Sample\\tun_singbox\">\n\t\t\t<CopyToOutputDirectory>Never</CopyToOutputDirectory>\n\t\t</EmbeddedResource>\n\t\t<EmbeddedResource Include=\"Sample\\tun_singbox_dns\">\n\t\t\t<CopyToOutputDirectory>Never</CopyToOutputDirectory>\n\t\t</EmbeddedResource>\n\t\t<EmbeddedResource Include=\"Sample\\custom_routing_black\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\custom_routing_global\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\custom_routing_locked\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\custom_routing_rules\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\custom_routing_white\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\SampleClientConfig\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\SampleHttprequest\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\SampleHttpresponse\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\SampleInbound\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\tun_singbox_rules\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"Sample\\tun_singbox_inbound\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>\n\t\t<EmbeddedResource Include=\"Sample\\dns_v2ray_normal\">\n\t\t\t<CopyToOutputDirectory>Never</CopyToOutputDirectory>\n\t\t</EmbeddedResource>\n\t\t<EmbeddedResource Include=\"Sample\\dns_singbox_normal\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>  \n        <EmbeddedResource Include=\"v2rayN.ico\">\n          <CopyToOutputDirectory>Never</CopyToOutputDirectory>\n        </EmbeddedResource>\n        <Resource Include=\"Resources\\NotifyIcon1.ico\" />\n        <Resource Include=\"Resources\\NotifyIcon2.ico\" />\n        <Resource Include=\"Resources\\NotifyIcon3.ico\" />\n        <Resource Include=\"v2rayN.ico\">\n          <CopyToOutputDirectory>Always</CopyToOutputDirectory>\n        </Resource>\n        <Resource Include=\"Views\\v2rayN.ico\" />\n    </ItemGroup> \t \n\t\n\t<ItemGroup>\n\t  <ProjectReference Include=\"..\\PacLib\\PacLib.csproj\" />\n\t  <ProjectReference Include=\"..\\ProtosLib\\ProtosLib.csproj\" />\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t\t<Compile Update=\"Resx\\Hiddify.Designer.cs\">\n\t\t  <DesignTime>True</DesignTime>\n\t\t  <AutoGen>True</AutoGen>\n\t\t  <DependentUpon>Hiddify.resx</DependentUpon>\n\t\t</Compile>\n\t\t<Compile Update=\"Resx\\ResUI.Designer.cs\">\n\t\t\t<DesignTime>True</DesignTime>\n\t\t\t<AutoGen>True</AutoGen>\n\t\t\t<DependentUpon>ResUI.resx</DependentUpon>\n\t\t</Compile>\t\t\n\t</ItemGroup>\n\n\t<ItemGroup>\n\t  <EmbeddedResource Update=\"Resx\\Hiddify.resx\">\n\t    <Generator>ResXFileCodeGenerator</Generator>\n\t    <LastGenOutput>Hiddify.Designer.cs</LastGenOutput>\n\t  </EmbeddedResource>\n\t  <EmbeddedResource Update=\"Resx\\ResUI.resx\">\n\t    <Generator>PublicResXFileCodeGenerator</Generator>\n\t    <LastGenOutput>ResUI.Designer.cs</LastGenOutput>\n\t  </EmbeddedResource>\n\t  <EmbeddedResource Update=\"Resx\\ResUI.zh-Hans.resx\">\n\t    <Generator>PublicResXFileCodeGenerator</Generator>\n\t  </EmbeddedResource>\n\t  <EmbeddedResource Update=\"Resx\\ResUI.fa-Ir.resx\">\n\t    <Generator>PublicResXFileCodeGenerator</Generator>\n\t  </EmbeddedResource>\n\t  <EmbeddedResource Update=\"Resx\\ResUI.ru.resx\">\n\t    <Generator>PublicResXFileCodeGenerator</Generator>\n\t  </EmbeddedResource>\n\t</ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "v2rayN/v2rayN.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio Version 17\nVisualStudioVersion = 17.3.32811.315\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"v2rayN\", \"v2rayN\\v2rayN.csproj\", \"{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ProtosLib\", \"ProtosLib\\ProtosLib.csproj\", \"{C5F24BB0-9CC1-44DD-82FF-D545F081819B}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"PacLib\", \"PacLib\\PacLib.csproj\", \"{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"HiddifyUpgradeN\", \"HiddifyUpgradeN\\HiddifyUpgradeN.csproj\", \"{3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"HiddifyRestartN\", \"HiddifyRestartN\\HiddifyRestartN.csproj\", \"{89185DF9-A4F2-4A1E-A290-EA02959C37DA}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{6DE127CA-1763-4236-B297-D2EF9CB2EC9B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{C5F24BB0-9CC1-44DD-82FF-D545F081819B}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{EE4E6CD8-8353-446B-8F29-A841A02AE5EC}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{3CD0B9E8-331B-42C6-A395-4DA0FD4BC8EB}.Release|Any CPU.Build.0 = Release|Any CPU\n\t\t{89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{89185DF9-A4F2-4A1E-A290-EA02959C37DA}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\n\tGlobalSection(ExtensibilityGlobals) = postSolution\n\t\tSolutionGuid = {43E06CBD-3DA9-40A3-8E4D-F0943CB0DD32}\n\tEndGlobalSection\nEndGlobal\n"
  }
]