diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index acb3eb238ac..0508af3ebb1 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,3 +1,3 @@
# These are supported funding model platforms
ko_fi: hoothin
-custom: ["https://paypal.me/hoothin", "https://afdian.net/a/hoothin"]
+custom: ["https://paypal.me/hoothin", "https://afdian.com/a/hoothin"]
diff --git a/.github/ISSUE_TEMPLATE/custom-rule-request.md b/.github/ISSUE_TEMPLATE/custom-rule-request.md
index 0ceb38d2984..d012e0245f3 100644
--- a/.github/ISSUE_TEMPLATE/custom-rule-request.md
+++ b/.github/ISSUE_TEMPLATE/custom-rule-request.md
@@ -1,7 +1,7 @@
---
name: Custom rule request
about: Seek help for custom rule. Please publish the issue according to the guidelines,
- otherwise the request will be ignored and closed directly. Your understanding and
+ otherwise the request ⚠will be ignored and closed directly⚠. Your understanding and
cooperation are appreciated.
title: ''
labels: ''
@@ -10,7 +10,7 @@ assignees: ''
---
**The url of site**
-The example urls of site. ⚠**Do not paste only domain without pathname**⚠.
+The example urls of site. ⚠**Do not paste only domain without pathname, or I'll close the issue without explanation**⚠.
**Is your request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
diff --git a/.github/workflows/build-dist.yml b/.github/workflows/build-dist.yml
new file mode 100644
index 00000000000..ef4f9880fb6
--- /dev/null
+++ b/.github/workflows/build-dist.yml
@@ -0,0 +1,33 @@
+name: Build Picviewer CE+ Dist
+
+on:
+ push:
+ branches:
+ - master
+ paths:
+ - 'Picviewer CE*/Picviewer CE*.user.js'
+ workflow_dispatch:
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout repository
+ uses: actions/checkout@v4
+
+ - name: Replace require paths, add timestamp, and create dist file
+ run: |
+ sed -E \
+ -e "s#https://update.greasyfork.org/scripts/6158/([0-9]+)/GM_config%20CN.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/GM_config%20CN.js?v=\1#g" \
+ -e "s#https://update.greasyfork.org/scripts/438080/([0-9]+)/pvcep_rules.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_rules.js?v=\1#g" \
+ -e "s#https://update.greasyfork.org/scripts/440698/([0-9]+)/pvcep_lang.js#https://hoothin.github.io/UserScripts/Picviewer%20CE%2B/pvcep_lang.js?v=\1#g" \
+ "Picviewer CE+/Picviewer CE+.user.js" > "Picviewer CE+/dist.user.js"
+
+ - name: Commit and push dist.user.js
+ run: |
+ git config --local user.email "rixixi@gmail.com"
+ git config --local user.name "hoothin-update"
+ git add "Picviewer CE+/dist.user.js"
+ git commit -m "chore(Picviewer CE+): Auto-generate dist.user.js"
+ git push https://${{ secrets.ACTION_SECRET }}@github.com/${{ github.repository }}
diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml
index 00b864d6d2c..9bdd4e3eec5 100644
--- a/.github/workflows/jekyll-gh-pages.yml
+++ b/.github/workflows/jekyll-gh-pages.yml
@@ -8,6 +8,8 @@ on:
paths-ignore:
- 'Pagetual/items_all.json'
- 'Pagetual/pagetualRules.json'
+ - '.github/*'
+ - '.github/*/*'
workflow_run:
workflows: ["Update Version on File Change"]
types:
diff --git a/.github/workflows/json-validator.yml b/.github/workflows/json-validator.yml
index a726236d040..01911cc1730 100644
--- a/.github/workflows/json-validator.yml
+++ b/.github/workflows/json-validator.yml
@@ -13,9 +13,9 @@ jobs:
- uses: actions/checkout@v4
- name: json-yaml-validate
- uses: GrantBirki/json-yaml-validate@v3.0.0
+ uses: GrantBirki/json-yaml-validate@v5
id: json-yaml-validate
with:
json_schema: Pagetual/pagetual.schema.json
files: |
- Pagetual/pagetualRules.json
\ No newline at end of file
+ Pagetual/pagetualRules.json
diff --git a/91wii/91wii.user.js b/91wii/91wii.user.js
deleted file mode 100644
index b94c7d4fd79..00000000000
--- a/91wii/91wii.user.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// ==UserScript==
-// @name 91wii
-// @namespace hoothin
-// @version 0.6
-// @description 91wii签到
-// @author hoothin
-// @match https://*.91wii.com/*
-// @match https://*.91tvg.com/*
-// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
-// @run-at document-idle
-// @grant unsafeWindow
-// ==/UserScript==
-
-(function() {
- 'use strict';
- setTimeout(()=>{
- var formula = document.querySelector("b"),dcsignin = document.querySelector("#dcsignin_tips");
- if(formula && /^[\d\s\+-=?]+$/.test(formula.innerText.trim())){
- setTimeout(function(){
- document.querySelector("input[type=text]").value=eval(formula.innerText.match(/[\d\s\+-]+/)[0]);
- document.querySelector("input[type=submit]").click();
- },10);
- }else if(dcsignin){
- if(dcsignin.style.background.indexOf("signin_yes") != -1)return;
- unsafeWindow.showWindow('sign', 'plugin.php?id=dc_signin:sign');
- var checkTimes=0;
- let signInterval=setInterval(()=>{
- var signWin=document.querySelector("#fwin_sign");
- if(signWin){
- signWin.style.display="none";
- }
- var dialogWin=document.querySelector("#fwin_dialog");
- if(dialogWin){
- dialogWin.style.display="none";
- }
- let emotIndex=parseInt(Math.random() * 10) + 1;
- if(document.querySelector("#emot_" + emotIndex)){
- clearInterval(signInterval);
- document.querySelector("#emot_" + emotIndex).click();
- //document.querySelector('#content').value = '君子有四时,朝以听政,昼以访问,夕以修令,夜以安身。';
- document.querySelector("button[name=signpn]").click();
- unsafeWindow.hideWindow('sign');
- }else if(checkTimes++>15){
- clearInterval(signInterval);
- unsafeWindow.hideWindow('sign');
- }
- }, 100);
- }
- },2000);
-})();
\ No newline at end of file
diff --git a/91wii/README.md b/91wii/README.md
deleted file mode 100644
index d7cb01b5315..00000000000
--- a/91wii/README.md
+++ /dev/null
@@ -1 +0,0 @@
-# 91wii 自动作答数学题,自动签到
diff --git a/BingBgForBaidu/BingBgForBaidu.user.js b/BingBgForBaidu/BingBgForBaidu.user.js
index 1c1e51267e0..ba0fa832396 100644
--- a/BingBgForBaidu/BingBgForBaidu.user.js
+++ b/BingBgForBaidu/BingBgForBaidu.user.js
@@ -2,7 +2,7 @@
// @name 百Bing图
// @name:en BingBgForBaidu
// @namespace hoothin
-// @version 2.3.37
+// @version 2.3.45
// @description 给百度首页换上Bing的背景图,并添加背景图链接与日历组件
// @description:en Just change the background image of baidu.com to bing.com
// @author hoothin
@@ -31,7 +31,7 @@
if(!head.classList.contains("s-skin-hasbg")){
head.classList.add("s-skin-hasbg");
head.classList.add("s-opacity-50");
- GM_addStyle(".s-opacity-50 .s-opacity-border1-top{border-top-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border1-bottom{border-bottom-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border1-left{border-left-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border1-right{border-right-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border2-top{border-top-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border2-bottom{border-bottom-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border2-left{border-left-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border2-right{border-right-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border3-top{border-top-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border3-bottom{border-bottom-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border3-left{border-left-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border3-right{border-right-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border4-top{border-top-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border4-bottom{border-bottom-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border4-left{border-left-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border4-right{border-right-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border5-top{border-top-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border5-bottom{border-bottom-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border5-left{border-left-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border5-right{border-right-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border6-top{border-top-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border6-bottom{border-bottom-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border6-left{border-left-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border6-right{border-right-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border7-top{border-top-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-border7-bottom{border-bottom-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-border7-left{border-left-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-border7-right{border-right-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-blank1{border-color: rgba(206,206,206,0.5) !important;}.s-opacity-50 .s-opacity-blank2{border-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-blank3{border-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-blank4{border-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-blank5{border-color: rgba(216,216,216,0.5) !important;}.s-opacity-50 .s-opacity-blank6{border-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-blank7{border-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-blank8{border-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-scroll{border-color: rgba(227,227,227,0.5) !important;}.s-opacity-50 .s-opacity-scroll{border-left-color: rgba(225,225,225,0.5) !important;}.s-opacity-50 .s-opacity-scroll{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(227,227,227,0.5)),to(rgba(227,227,227,0.5))) !important;background-image: -moz-linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;background-image: linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FE3E3E3,endColorstr=#7FE3E3E3) !important;}.s-opacity-50 .s-opacity-scroll-slider{border-color: rgba(225,225,225,0.5) !important;}.s-opacity-50 .s-opacity-scroll-slider{border-bottom-color: rgba(212,212,212,0.5) !important;}.s-opacity-50 .s-opacity-scroll-slider{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.5)),to(rgba(255,255,255,0.5))) !important;background-image: -moz-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FFFFFFF,endColorstr=#7FFFFFFF) !important;}.s-opacity-50 .s-opacity-background1{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(243,243,243,0.5)),to(rgba(243,243,243,0.5))) !important;background-image: -moz-linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;background-image: linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FF3F3F3,endColorstr=#7FF3F3F3) !important;}.s-opacity-50 .s-opacity-background2{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(248,248,248,0.5)),to(rgba(248,248,248,0.5))) !important;background-image: -moz-linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;background-image: linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FF8F8F8,endColorstr=#7FF8F8F8) !important;}.s-opacity-50 .s-opacity-white-background{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.5)),to(rgba(255,255,255,0.5))) !important;background-image: -moz-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FFFFFFF,endColorstr=#7FFFFFFF) !important;}.s-opacity-50 .s-opacity-menu1{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0.4)),to(rgba(0,0,0,0.4))) !important;background-image: -moz-linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;background-image: -ms-linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;background-image: -o-linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;background-image: linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000) !important;}.s-opacity-50 .s-opacity-foreground{opacity: 0.5;filter: alpha(opacity=50);}.s-opacity-50 .s-opacity-max{opacity: 0.4;filter: alpha(opacity=40);}.s-opacity-50 .s-opacity-bottommoremenu{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(rgba(0,0,0,0.45))) !important;background-image: -moz-linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;background-image: -ms-linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;background-image: -o-linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;background-image: linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00000000,endColorstr=#72000000) !important;}.s-opacity-50 .s-opacity-topmoremenu{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0.45)),to(rgba(0,0,0,0))) !important;background-image: -moz-linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;background-image: -ms-linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;background-image: -o-linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;background-image: linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#72000000,endColorstr=#00000000) !important;}");
+ GM_addStyle("[tpl='ai-tools-panel'],.fixed-skin-wrapper{display: none!important;}#bottom_layer{position:absolute!important;}.s-opacity-50 .s-opacity-border1-top{border-top-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border1-bottom{border-bottom-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border1-left{border-left-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border1-right{border-right-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-border2-top{border-top-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border2-bottom{border-bottom-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border2-left{border-left-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border2-right{border-right-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-border3-top{border-top-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border3-bottom{border-bottom-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border3-left{border-left-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border3-right{border-right-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-border4-top{border-top-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border4-bottom{border-bottom-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border4-left{border-left-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border4-right{border-right-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-border5-top{border-top-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border5-bottom{border-bottom-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border5-left{border-left-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border5-right{border-right-color: rgba(243,243,243,0.5) !important;}.s-opacity-50 .s-opacity-border6-top{border-top-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border6-bottom{border-bottom-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border6-left{border-left-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border6-right{border-right-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-border7-top{border-top-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-border7-bottom{border-bottom-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-border7-left{border-left-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-border7-right{border-right-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-blank1{border-color: rgba(206,206,206,0.5) !important;}.s-opacity-50 .s-opacity-blank2{border-color: rgba(233,233,233,0.5) !important;}.s-opacity-50 .s-opacity-blank3{border-color: rgba(240,240,240,0.5) !important;}.s-opacity-50 .s-opacity-blank4{border-color: rgba(218,218,218,0.5) !important;}.s-opacity-50 .s-opacity-blank5{border-color: rgba(216,216,216,0.5) !important;}.s-opacity-50 .s-opacity-blank6{border-color: rgba(238,238,238,0.5) !important;}.s-opacity-50 .s-opacity-blank7{border-color: rgba(234,234,234,0.5) !important;}.s-opacity-50 .s-opacity-blank8{border-color: rgba(226,226,226,0.5) !important;}.s-opacity-50 .s-opacity-scroll{border-color: rgba(227,227,227,0.5) !important;}.s-opacity-50 .s-opacity-scroll{border-left-color: rgba(225,225,225,0.5) !important;}.s-opacity-50 .s-opacity-scroll{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(227,227,227,0.5)),to(rgba(227,227,227,0.5))) !important;background-image: -moz-linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;background-image: linear-gradient(rgba(227,227,227,0.5) 0%,rgba(227,227,227,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FE3E3E3,endColorstr=#7FE3E3E3) !important;}.s-opacity-50 .s-opacity-scroll-slider{border-color: rgba(225,225,225,0.5) !important;}.s-opacity-50 .s-opacity-scroll-slider{border-bottom-color: rgba(212,212,212,0.5) !important;}.s-opacity-50 .s-opacity-scroll-slider{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.5)),to(rgba(255,255,255,0.5))) !important;background-image: -moz-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FFFFFFF,endColorstr=#7FFFFFFF) !important;}.s-opacity-50 .s-opacity-background1{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(243,243,243,0.5)),to(rgba(243,243,243,0.5))) !important;background-image: -moz-linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;background-image: linear-gradient(rgba(243,243,243,0.5) 0%,rgba(243,243,243,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FF3F3F3,endColorstr=#7FF3F3F3) !important;}.s-opacity-50 .s-opacity-background2{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(248,248,248,0.5)),to(rgba(248,248,248,0.5))) !important;background-image: -moz-linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;background-image: linear-gradient(rgba(248,248,248,0.5) 0%,rgba(248,248,248,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FF8F8F8,endColorstr=#7FF8F8F8) !important;}.s-opacity-50 .s-opacity-white-background{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(255,255,255,0.5)),to(rgba(255,255,255,0.5))) !important;background-image: -moz-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -ms-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: -o-linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;background-image: linear-gradient(rgba(255,255,255,0.5) 0%,rgba(255,255,255,0.5) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#7FFFFFFF,endColorstr=#7FFFFFFF) !important;}.s-opacity-50 .s-opacity-menu1{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0.4)),to(rgba(0,0,0,0.4))) !important;background-image: -moz-linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;background-image: -ms-linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;background-image: -o-linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;background-image: linear-gradient(rgba(0,0,0,0.4) 0%,rgba(0,0,0,0.4) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#66000000,endColorstr=#66000000) !important;}.s-opacity-50 .s-opacity-foreground{opacity: 0.5;filter: alpha(opacity=50);}.s-opacity-50 .s-opacity-max{opacity: 0.4;filter: alpha(opacity=40);}.s-opacity-50 .s-opacity-bottommoremenu{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0)),to(rgba(0,0,0,0.45))) !important;background-image: -moz-linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;background-image: -ms-linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;background-image: -o-linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;background-image: linear-gradient(rgba(0,0,0,0) 0%,rgba(0,0,0,0.45) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00000000,endColorstr=#72000000) !important;}.s-opacity-50 .s-opacity-topmoremenu{background: none !important;background-image: -webkit-gradient(linear,left top,left bottom,from(rgba(0,0,0,0.45)),to(rgba(0,0,0,0))) !important;background-image: -moz-linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;background-image: -ms-linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;background-image: -o-linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;background-image: linear-gradient(rgba(0,0,0,0.45) 0%,rgba(0,0,0,0) 100%) !important;filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#72000000,endColorstr=#00000000) !important;}");
}
var bingBgLink=document.createElement("a");
bingBgLink.innerHTML="Bing图 ";
@@ -95,11 +95,11 @@
//riliLink.innerHTML=""+$(".op-calendar-new-right-date,.op-calendar-pc-right-date",iframe.contentDocument).html()+" ";
riliLink.onmouseenter=function(){
clearTimeout(t);
- $(iframe).show(200);
- iframeDoc.scrollTop(137);
- iframeDoc.scrollLeft(130);
- iframe.width=600;
- iframe.height=665;
+ $(iframe).show(200);
+ iframeDoc.scrollTop(125);
+ iframeDoc.scrollLeft(145);
+ iframe.width=618;
+ iframe.height=630;
};
riliLink.onmouseleave=function(){
clearTimeout(t);
@@ -116,24 +116,24 @@
$(iframe).hide(500);
},100);
};
- var holiday=$('.cos-search-link',iframe.contentDocument)[0];
+ var holiday=$('.cos-search-link,.sc-search-link',iframe.contentDocument)[0];
if(holiday){
var title=holiday.innerText.slice(0, -1);
riliLink.innerHTML+=title?" "+title+" ":"";
riliLink.title=title;
}
};
- var skinContainer=document.querySelector(".s-skin-container");
- if(!skinContainer){
- skinContainer=document.getElementsByTagName("body")[0];
- GM_addStyle(".s-top-right .ai-entry-right-nologin,.s-top-right .operate-wrapper-nologin{right:362px;}.hot-refresh{padding-bottom:7px;}.hot-title>div,.hot-refresh{background-color: #f0f8ff95; border-radius: 3px 3px 0 0}.s-hotsearch-content{position: absolute; background-color: #f0f8ff95; border-radius: 0 0 5px 5px;padding-right: 2px;}.s_ipt{margin:0!important;}.s_ipt_wr{border-radius: 10px 4px 4px 10px;border-radius: 10px 0 0 10px;background: #fff!important;}#qrcodeCon{display:none}body{position:fixed;_position:absolute;top:0;left:0;height:100%;width:100%;min-width:1000px;z-index:-10;background-position:center 0;background-repeat:no-repeat;background-size:cover;-webkit-background-size:cover;-o-background-size:cover;zoom:1;}");
- var inputsu=document.querySelector("input#su");
- var clickHandler=e=>{
- if(skinContainer)skinContainer.style.backgroundImage="";
- else inputsu.removeEventListener("click",clickHandler);
- };
- inputsu.addEventListener("click",clickHandler);
+ var skinContainer=document.getElementsByTagName("body")[0];
+ if (!document.querySelector(".aigc-skin-bg,#s_mancard_main")) {
+ GM_addStyle(".s-news-rank-content{max-height: 180px; width: 99%; overflow-y: auto; overflow-x: hidden;}.s-top-right .ai-entry-right-nologin,.s-top-right .operate-wrapper-nologin{right:362px;}.hot-refresh{padding-bottom:7px;}.hot-title>div,.hot-refresh{border-radius: 3px 3px 0 0}.s-hotsearch-title>a,.s-hotsearch-title>a>div{padding: 5px;background-color: #f0f8ff95;border-radius: 5px;}.s-hotsearch-content{position: absolute; background-color: #f0f8ff95; border-radius: 5px;padding: 5px;}");
}
+ GM_addStyle(".s_ipt{margin:0!important;}.s_ipt_wr{border-radius: 10px 4px 4px 10px;border-radius: 10px 0 0 10px;background: #fff!important;}#qrcodeCon{display:none}body{position:fixed;_position:absolute;top:0;left:0;height:100%;width:100%;min-width:1000px;z-index:-10;background-position:center 0;background-repeat:no-repeat;background-size:cover;-webkit-background-size:cover;-o-background-size:cover;zoom:1;}");
+ var inputsu=document.querySelector("input#su");
+ var clickHandler=e=>{
+ if(skinContainer)skinContainer.style.backgroundImage="";
+ else inputsu.removeEventListener("click",clickHandler);
+ };
+ inputsu.addEventListener("click",clickHandler);
var bingImgObj=GM_getValue("bingImgObj");
if(bingImgObj){
skinContainer.style.backgroundImage = "url(\""+bingImgObj.base64+"\")";
@@ -156,7 +156,7 @@
logo.style.display="initial";
}
}
- var input=document.querySelector("#kw");
+ var input=document.querySelector("#kw,#chat-textarea");
var headWrapper=document.querySelector("#head_wrapper");
let inputHandler = e => {
setTimeout(() => {
@@ -168,16 +168,21 @@
}, 0);
};
input.addEventListener('input', inputHandler);
+ var submit=document.querySelector("#chat-submit-button");
+ submit.addEventListener('click', e => {
+ if(skinContainer)skinContainer.style.backgroundImage="";
+ skinContainer=null;
+ });
GM_xmlhttpRequest({
method: 'GET',
- url: "http://global.bing.com/HPImageArchive.aspx?format=js&idx=0&pid=hp&video=1&n=1",
+ url: "https://global.bing.com/HPImageArchive.aspx?format=js&idx=0&pid=hp&video=1&n=1",
onload: function(result) {
var jsonData=null;
try {
jsonData=JSON.parse(result.responseText);
var bgUrl=jsonData.images[0].url;
if(!/^https?:\/\//.test(bgUrl)){
- bgUrl="http://global.bing.com"+bgUrl;
+ bgUrl="https://global.bing.com"+bgUrl;
}
bingBgLink.title=jsonData.images[0].copyright;
bingBgLink.href=bgUrl;
diff --git a/BingBgForBaidu/BingBgForGoogle.user.js b/BingBgForBaidu/BingBgForGoogle.user.js
new file mode 100644
index 00000000000..dba6149ffdb
--- /dev/null
+++ b/BingBgForBaidu/BingBgForGoogle.user.js
@@ -0,0 +1,320 @@
+// ==UserScript==
+// @name BingBgForGoogle
+// @name:zh-CN 谷Bing图
+// @name:zh-TW 谷Bing圖
+// @namespace hoothin
+// @version 0.3
+// @description Just change the background image of Google homepage to Bing
+// @description:zh-CN 给谷歌首页换上 Bing 的背景图
+// @description:zh-TW 給 Google 首頁換上 Bing 的背景圖
+// @author hoothin
+// @grant GM_xmlhttpRequest
+// @grant GM_setValue
+// @grant GM_getValue
+// @grant GM_addStyle
+// @grant GM_registerMenuCommand
+// @grant unsafeWindow
+// @connect global.bing.com
+// @connect cn.bing.com
+// @license MIT License
+// @match *://www.google.com/*
+// @match *://www.google.ad/*
+// @match *://www.google.ae/*
+// @match *://www.google.com.af/*
+// @match *://www.google.com.ag/*
+// @match *://www.google.al/*
+// @match *://www.google.am/*
+// @match *://www.google.co.ao/*
+// @match *://www.google.com.ar/*
+// @match *://www.google.as/*
+// @match *://www.google.at/*
+// @match *://www.google.com.au/*
+// @match *://www.google.az/*
+// @match *://www.google.ba/*
+// @match *://www.google.com.bd/*
+// @match *://www.google.be/*
+// @match *://www.google.bf/*
+// @match *://www.google.bg/*
+// @match *://www.google.com.bh/*
+// @match *://www.google.bi/*
+// @match *://www.google.bj/*
+// @match *://www.google.com.bn/*
+// @match *://www.google.com.bo/*
+// @match *://www.google.com.br/*
+// @match *://www.google.bs/*
+// @match *://www.google.bt/*
+// @match *://www.google.co.bw/*
+// @match *://www.google.by/*
+// @match *://www.google.com.bz/*
+// @match *://www.google.ca/*
+// @match *://www.google.cd/*
+// @match *://www.google.cf/*
+// @match *://www.google.cg/*
+// @match *://www.google.ch/*
+// @match *://www.google.ci/*
+// @match *://www.google.co.ck/*
+// @match *://www.google.cl/*
+// @match *://www.google.cm/*
+// @match *://www.google.cn/*
+// @match *://www.google.com.co/*
+// @match *://www.google.co.cr/*
+// @match *://www.google.com.cu/*
+// @match *://www.google.cv/*
+// @match *://www.google.com.cy/*
+// @match *://www.google.cz/*
+// @match *://www.google.de/*
+// @match *://www.google.dj/*
+// @match *://www.google.dk/*
+// @match *://www.google.dm/*
+// @match *://www.google.com.do/*
+// @match *://www.google.dz/*
+// @match *://www.google.com.ec/*
+// @match *://www.google.ee/*
+// @match *://www.google.com.eg/*
+// @match *://www.google.es/*
+// @match *://www.google.com.et/*
+// @match *://www.google.fi/*
+// @match *://www.google.com.fj/*
+// @match *://www.google.fm/*
+// @match *://www.google.fr/*
+// @match *://www.google.ga/*
+// @match *://www.google.ge/*
+// @match *://www.google.gg/*
+// @match *://www.google.com.gh/*
+// @match *://www.google.com.gi/*
+// @match *://www.google.gl/*
+// @match *://www.google.gm/*
+// @match *://www.google.gr/*
+// @match *://www.google.com.gt/*
+// @match *://www.google.gy/*
+// @match *://www.google.com.hk/*
+// @match *://www.google.hn/*
+// @match *://www.google.hr/*
+// @match *://www.google.ht/*
+// @match *://www.google.hu/*
+// @match *://www.google.co.id/*
+// @match *://www.google.ie/*
+// @match *://www.google.co.il/*
+// @match *://www.google.im/*
+// @match *://www.google.co.in/*
+// @match *://www.google.iq/*
+// @match *://www.google.is/*
+// @match *://www.google.it/*
+// @match *://www.google.je/*
+// @match *://www.google.com.jm/*
+// @match *://www.google.jo/*
+// @match *://www.google.co.jp/*
+// @match *://www.google.co.ke/*
+// @match *://www.google.com.kh/*
+// @match *://www.google.ki/*
+// @match *://www.google.kg/*
+// @match *://www.google.co.kr/*
+// @match *://www.google.com.kw/*
+// @match *://www.google.kz/*
+// @match *://www.google.la/*
+// @match *://www.google.com.lb/*
+// @match *://www.google.li/*
+// @match *://www.google.lk/*
+// @match *://www.google.co.ls/*
+// @match *://www.google.lt/*
+// @match *://www.google.lu/*
+// @match *://www.google.lv/*
+// @match *://www.google.com.ly/*
+// @match *://www.google.co.ma/*
+// @match *://www.google.md/*
+// @match *://www.google.me/*
+// @match *://www.google.mg/*
+// @match *://www.google.mk/*
+// @match *://www.google.ml/*
+// @match *://www.google.com.mm/*
+// @match *://www.google.mn/*
+// @match *://www.google.com.mt/*
+// @match *://www.google.mu/*
+// @match *://www.google.mv/*
+// @match *://www.google.mw/*
+// @match *://www.google.com.mx/*
+// @match *://www.google.com.my/*
+// @match *://www.google.co.mz/*
+// @match *://www.google.com.na/*
+// @match *://www.google.com.ng/*
+// @match *://www.google.com.ni/*
+// @match *://www.google.ne/*
+// @match *://www.google.nl/*
+// @match *://www.google.no/*
+// @match *://www.google.com.np/*
+// @match *://www.google.nr/*
+// @match *://www.google.nu/*
+// @match *://www.google.co.nz/*
+// @match *://www.google.com.om/*
+// @match *://www.google.com.pa/*
+// @match *://www.google.com.pe/*
+// @match *://www.google.com.pg/*
+// @match *://www.google.com.ph/*
+// @match *://www.google.com.pk/*
+// @match *://www.google.pl/*
+// @match *://www.google.pn/*
+// @match *://www.google.com.pr/*
+// @match *://www.google.ps/*
+// @match *://www.google.pt/*
+// @match *://www.google.com.py/*
+// @match *://www.google.com.qa/*
+// @match *://www.google.ro/*
+// @match *://www.google.ru/*
+// @match *://www.google.rw/*
+// @match *://www.google.com.sa/*
+// @match *://www.google.com.sb/*
+// @match *://www.google.sc/*
+// @match *://www.google.se/*
+// @match *://www.google.com.sg/*
+// @match *://www.google.sh/*
+// @match *://www.google.si/*
+// @match *://www.google.sk/*
+// @match *://www.google.com.sl/*
+// @match *://www.google.sn/*
+// @match *://www.google.so/*
+// @match *://www.google.sm/*
+// @match *://www.google.sr/*
+// @match *://www.google.st/*
+// @match *://www.google.com.sv/*
+// @match *://www.google.td/*
+// @match *://www.google.tg/*
+// @match *://www.google.co.th/*
+// @match *://www.google.com.tj/*
+// @match *://www.google.tl/*
+// @match *://www.google.tm/*
+// @match *://www.google.tn/*
+// @match *://www.google.to/*
+// @match *://www.google.com.tr/*
+// @match *://www.google.tt/*
+// @match *://www.google.com.tw/*
+// @match *://www.google.co.tz/*
+// @match *://www.google.com.ua/*
+// @match *://www.google.co.ug/*
+// @match *://www.google.co.uk/*
+// @match *://www.google.com.uy/*
+// @match *://www.google.co.uz/*
+// @match *://www.google.com.vc/*
+// @match *://www.google.co.ve/*
+// @match *://www.google.co.vi/*
+// @match *://www.google.com.vn/*
+// @match *://www.google.vu/*
+// @match *://www.google.ws/*
+// @match *://www.google.rs/*
+// @match *://www.google.co.za/*
+// @match *://www.google.co.zm/*
+// @match *://www.google.co.zw/*
+// @match *://www.google.cat/*
+// @downloadURL https://update.greasyfork.org/scripts/503741/BingBgForGoogle.user.js
+// @updateURL https://update.greasyfork.org/scripts/503741/BingBgForGoogle.meta.js
+// ==/UserScript==
+
+(function() {
+ 'use strict';
+ if (/\?q=/.test(location.href)) return;
+ let LinkPa = document.querySelector("[data-ogbl]");
+ if (!LinkPa) return;
+ let bingBgLink = document.createElement("a");
+ bingBgLink.className = LinkPa.firstChild.firstChild.className;
+ bingBgLink.target = "_blank";
+ bingBgLink.innerText = "Bing Bg";
+ let linkDiv = document.createElement("div");
+ linkDiv.className = LinkPa.firstChild.className;
+ linkDiv.appendChild(bingBgLink);
+ LinkPa.appendChild(linkDiv);
+ let skinContainer = document.body;
+ GM_addStyle(`
+ body{
+ background-position: center 0;
+ background-repeat: no-repeat;
+ background-size: cover;
+ -webkit-background-size: cover;
+ -o-background-size: cover;
+ }
+ #gb{
+ background-color: unset!important;
+ }
+ [role="navigation"],[role="contentinfo"]{
+ background-color: rgb(32 33 36 / 50%)!important;
+ }
+ #gb *,[role="contentinfo"] *{
+ color: white!important;
+ }
+ `);
+
+ let btnK = document.querySelector("input[name='btnK']");
+ let clickHandler = e => {
+ skinContainer.style.backgroundImage = "";
+ };
+ btnK.addEventListener("click",clickHandler);
+ let bingImgObj = GM_getValue("bingImgObj");
+ if (bingImgObj) {
+ skinContainer.style.backgroundImage = "url(\"" + bingImgObj.base64 + "\")";
+ }
+
+ GM_xmlhttpRequest({
+ method: 'GET',
+ url: "https://global.bing.com/HPImageArchive.aspx?format=js&idx=0&pid=hp&video=1&n=1",
+ onload: function(result) {
+ let jsonData = null;
+ try {
+ jsonData = JSON.parse(result.responseText);
+ let bgUrl = jsonData.images[0].url;
+ if (!/^https?:\/\//.test(bgUrl)) {
+ bgUrl = "https://global.bing.com" + bgUrl;
+ }
+ bingBgLink.title = jsonData.images[0].copyright;
+ bingBgLink.href = bgUrl;
+ if (bingImgObj && bingImgObj.url == bgUrl) return;
+ if (!bingImgObj) skinContainer.style.backgroundImage = "url(\"" + bgUrl + "\")";
+ GM_xmlhttpRequest({
+ method: 'GET',
+ url: bgUrl,
+ responseType: "blob",
+ onload: function(r) {
+ let blob = r.response;
+ let fr = new FileReader();
+ fr.readAsDataURL(blob);
+ fr.onload = function (e) {
+ let base64ImgData = e.target.result;
+ GM_setValue("bingImgObj",{url: bgUrl, base64: base64ImgData});
+ };
+ }
+ });
+ } catch (e) {
+ console.log(e);
+ }
+ }
+ });
+ let blurStyle;
+ function createBlur() {
+ if (!blurStyle) {
+ blurStyle = document.createElement("style");
+ blurStyle.innerText = `
+ body::before{
+ content: " ";
+ display: block;
+ position: absolute;
+ left: 0;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ background: inherit;
+ filter: blur(5px);
+ z-index: -1;
+ }`;
+ }
+ document.head.appendChild(blurStyle);
+ }
+ if (GM_getValue("blur")) {
+ createBlur();
+ }
+ GM_registerMenuCommand("Change blur", () => {
+ if (blurStyle && blurStyle.parentNode) {
+ GM_setValue("blur", false);
+ blurStyle.parentNode.removeChild(blurStyle);
+ } else {
+ GM_setValue("blur", true);
+ createBlur();
+ }
+ });
+})();
\ No newline at end of file
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
new file mode 100644
index 00000000000..b6d486bd5e3
--- /dev/null
+++ b/CODE_OF_CONDUCT.md
@@ -0,0 +1,128 @@
+# Contributor Covenant Code of Conduct
+
+## Our Pledge
+
+We as members, contributors, and leaders pledge to make participation in our
+community a harassment-free experience for everyone, regardless of age, body
+size, visible or invisible disability, ethnicity, sex characteristics, gender
+identity and expression, level of experience, education, socio-economic status,
+nationality, personal appearance, race, religion, or sexual identity
+and orientation.
+
+We pledge to act and interact in ways that contribute to an open, welcoming,
+diverse, inclusive, and healthy community.
+
+## Our Standards
+
+Examples of behavior that contributes to a positive environment for our
+community include:
+
+* Demonstrating empathy and kindness toward other people
+* Being respectful of differing opinions, viewpoints, and experiences
+* Giving and gracefully accepting constructive feedback
+* Accepting responsibility and apologizing to those affected by our mistakes,
+ and learning from the experience
+* Focusing on what is best not just for us as individuals, but for the
+ overall community
+
+Examples of unacceptable behavior include:
+
+* The use of sexualized language or imagery, and sexual attention or
+ advances of any kind
+* Trolling, insulting or derogatory comments, and personal or political attacks
+* Public or private harassment
+* Publishing others' private information, such as a physical or email
+ address, without their explicit permission
+* Other conduct which could reasonably be considered inappropriate in a
+ professional setting
+
+## Enforcement Responsibilities
+
+Community leaders are responsible for clarifying and enforcing our standards of
+acceptable behavior and will take appropriate and fair corrective action in
+response to any behavior that they deem inappropriate, threatening, offensive,
+or harmful.
+
+Community leaders have the right and responsibility to remove, edit, or reject
+comments, commits, code, wiki edits, issues, and other contributions that are
+not aligned to this Code of Conduct, and will communicate reasons for moderation
+decisions when appropriate.
+
+## Scope
+
+This Code of Conduct applies within all community spaces, and also applies when
+an individual is officially representing the community in public spaces.
+Examples of representing our community include using an official e-mail address,
+posting via an official social media account, or acting as an appointed
+representative at an online or offline event.
+
+## Enforcement
+
+Instances of abusive, harassing, or otherwise unacceptable behavior may be
+reported to the community leaders responsible for enforcement at
+rixixi@gmail.com.
+All complaints will be reviewed and investigated promptly and fairly.
+
+All community leaders are obligated to respect the privacy and security of the
+reporter of any incident.
+
+## Enforcement Guidelines
+
+Community leaders will follow these Community Impact Guidelines in determining
+the consequences for any action they deem in violation of this Code of Conduct:
+
+### 1. Correction
+
+**Community Impact**: Use of inappropriate language or other behavior deemed
+unprofessional or unwelcome in the community.
+
+**Consequence**: A private, written warning from community leaders, providing
+clarity around the nature of the violation and an explanation of why the
+behavior was inappropriate. A public apology may be requested.
+
+### 2. Warning
+
+**Community Impact**: A violation through a single incident or series
+of actions.
+
+**Consequence**: A warning with consequences for continued behavior. No
+interaction with the people involved, including unsolicited interaction with
+those enforcing the Code of Conduct, for a specified period of time. This
+includes avoiding interactions in community spaces as well as external channels
+like social media. Violating these terms may lead to a temporary or
+permanent ban.
+
+### 3. Temporary Ban
+
+**Community Impact**: A serious violation of community standards, including
+sustained inappropriate behavior.
+
+**Consequence**: A temporary ban from any sort of interaction or public
+communication with the community for a specified period of time. No public or
+private interaction with the people involved, including unsolicited interaction
+with those enforcing the Code of Conduct, is allowed during this period.
+Violating these terms may lead to a permanent ban.
+
+### 4. Permanent Ban
+
+**Community Impact**: Demonstrating a pattern of violation of community
+standards, including sustained inappropriate behavior, harassment of an
+individual, or aggression toward or disparagement of classes of individuals.
+
+**Consequence**: A permanent ban from any sort of public interaction within
+the community.
+
+## Attribution
+
+This Code of Conduct is adapted from the [Contributor Covenant][homepage],
+version 2.0, available at
+https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
+
+Community Impact Guidelines were inspired by [Mozilla's code of conduct
+enforcement ladder](https://github.com/mozilla/diversity).
+
+[homepage]: https://www.contributor-covenant.org
+
+For answers to common questions about this code of conduct, see the FAQ at
+https://www.contributor-covenant.org/faq. Translations are available at
+https://www.contributor-covenant.org/translations.
diff --git a/DownloadAllContent/DownloadAllContent.user.js b/DownloadAllContent/DownloadAllContent.user.js
index 5b2314a1959..de600e6dc11 100644
--- a/DownloadAllContent/DownloadAllContent.user.js
+++ b/DownloadAllContent/DownloadAllContent.user.js
@@ -2,9 +2,9 @@
// @name DownloadAllContent
// @name:zh-CN 怠惰小说下载器
// @name:zh-TW 怠惰小説下載器
-// @name:ja 怠惰者小説ダウンロードツール
+// @name:ja 怠惰小説ダウンローダー
// @namespace hoothin
-// @version 2.8.3.6
+// @version 2.8.3.19
// @description Lightweight web scraping script. Fetch and download main textual content from the current page, provide special support for novels
// @description:zh-CN 通用网站内容爬虫抓取工具,可批量抓取任意站点的小说、论坛内容等并保存为TXT文档
// @description:zh-TW 通用網站內容爬蟲抓取工具,可批量抓取任意站點的小說、論壇內容等並保存為TXT文檔
@@ -220,12 +220,12 @@ if (window.top != window.self) {
'use strict';
var indexReg=/^(\w.*)?PART\b|^Prologue|^(\w.*)?Chapter\s*[\-_]?\d+|分卷|^序$|^序\s*[·言章]|^前\s*言|^附\s*[录錄]|^引\s*[言子]|^摘\s*要|^[楔契]\s*子|^后\s*记|^後\s*記|^附\s*言|^结\s*语|^結\s*語|^尾\s*[声聲]|^最終話|^最终话|^番\s*外|^\d+[\s\.、,,)\-_::][^\d#\.]|^(\d|\s|\.)*[第(]?\s*[\d〇零一二两三四五六七八九十百千万萬-]+\s*[、)章节節回卷折篇幕集话話]/i;
var innerNextPage=/^\s*(下一[页頁张張]|next\s*page|次のページ)/i;
- var lang = navigator.appName=="Netscape"?navigator.language:navigator.userLanguage;
+ var lang=navigator.appName=="Netscape"?navigator.language:navigator.userLanguage;
var i18n={};
var rCats=[];
var processFunc, nextPageFunc;
- const AsyncFunction = Object.getPrototypeOf(async function(){}).constructor;
- var win=(typeof unsafeWindow=='undefined'? window : unsafeWindow);
+ const AsyncFunction=Object.getPrototypeOf(async function(){}).constructor;
+ var win=(typeof unsafeWindow=='undefined'?window:unsafeWindow);
switch (lang){
case "zh-CN":
case "zh-SG":
@@ -245,8 +245,13 @@ if (window.top != window.self) {
abort:"跳过此章",
save:"保存当前",
saveAsMd:"存为 Markdown",
- downThreadNum:"设置同时下载的线程数",
+ saveAsJSON: "存为 JSON",
+ downThreadNum:"设置同时下载的线程数,负数为单线程下载间隔",
+ enableTouch:"在移动端按→↓←↑的方向滑动屏幕画正方形立即开始下载",
customTitle:"自定义章节标题,输入内页文字对应选择器",
+ saveUrl: "储存 URL",
+ disableAutoStartSave: "禁用自动保存",
+ maxDlPerMin:"每分钟最大下载数",
reSortDefault:"默认按页面中位置排序章节",
reverseOrder:"反转章节排序",
saveBtn:"保存设置",
@@ -266,10 +271,11 @@ if (window.top != window.self) {
dacSaveAsZip:"下载为 zip",
dacSetCustomRule:"修改规则",
dacAddUrl:"添加章节",
+ prefix:"给章节名称添加前缀",
dacStartDownload:"下载选中",
- downloadShortcut:"下载章节",
- downloadSingleShortcut:"下载单页",
- downloadCustomShortcut:"自定义下载"
+ downloadShortcut:"下载章节快捷键",
+ downloadSingleShortcut:"下载单页快捷键",
+ downloadCustomShortcut:"自定义下载快捷键"
};
break;
case "zh":
@@ -291,8 +297,13 @@ if (window.top != window.self) {
abort:"跳過此章",
save:"保存當前",
saveAsMd:"存爲 Markdown",
- downThreadNum:"設置同時下載的綫程數",
+ saveAsJSON: "存爲 JSON",
+ downThreadNum:"設置同時下載的綫程數,負數為單線程下載間隔",
+ enableTouch:"在行動端按→↓←↑的方向滑動螢幕畫方立即開始下載",
customTitle:"自訂章節標題,輸入內頁文字對應選擇器",
+ saveUrl: "儲存 URL",
+ disableAutoStartSave: "禁用自動保存",
+ maxDlPerMin:"每分鐘最大下載數",
reSortDefault:"預設依頁面中位置排序章節",
reverseOrder:"反轉章節排序",
saveBtn:"儲存設定",
@@ -312,10 +323,11 @@ if (window.top != window.self) {
dacSaveAsZip:"下載為 zip",
dacSetCustomRule:"修改規則",
dacAddUrl:"新增章節",
+ prefix:"為章節名稱加上前綴",
dacStartDownload:"下載選取",
- downloadShortcut:"下載章節",
- downloadSingleShortcut:"下載單頁",
- downloadCustomShortcut:"自設下載"
+ downloadShortcut:"下載章節快速鍵",
+ downloadSingleShortcut:"下載單頁快速鍵",
+ downloadCustomShortcut:"自設下載快速鍵"
};
break;
case "ar":
@@ -336,46 +348,104 @@ if (window.top != window.self) {
case "ar-TN":
case "ar-YE":
i18n={
- fetch: "تحميل",
- info: "المصدر: #t#\nتم تنزيل الـ TXT بواسطة 'DownloadAllContent'",
- error: "فشل في تحميل الفصل الحالي",
- downloading: "......%s تحميل صفحات متبقية %s صفحات تم تحميلها، هناك %s",
- complete: "صفحات في المجموع %s اكتمل! حصلت على",
- del: "لتجاهل CSS تعيين محددات",
- custom: "تحميل مخصص",
- customInfo: "لروابط الفصول sss إدخال الروابط أو محددات",
- reSort: "إعادة الترتيب حسب العنوان",
- reSortUrl: "إعادة الترتيب حسب الروابط",
- setting: "فتح الإعدادات",
- searchRule: "قاعدة البحث",
- abort: "إيقاف",
- save: "حفظ",
- saveAsMd: "Markdown حفظ كـ",
- downThreadNum: "تعيين عدد الخيوط للتحميل",
- customTitle: "تخصيص عنوان الفصل، إدخال المحدد في الصفحة الداخلية",
- reSortDefault: "الترتيب الافتراضي حسب الموقع في الصفحة",
- reverseOrder: "عكس ترتيب الفصول",
- saveBtn: "حفظ الإعدادات",
- saveOk: "تم الحفظ",
- nextPage: "التحقق من الصفحة التالية في الفصل",
- nextPageReg: "مخصص للصفحة التالية RegExp",
- retainImage: "الاحتفاظ بعنوان الصورة إذا كانت هناك صور في النص",
- minTxtLength: "المحاولة مرة أخرى عندما يكون طول المحتوى أقل من هذا",
- showFilterList: "عرض نافذة التصفية والترتيب قبل التحميل",
- ok: "موافق",
- close: "إغلاق",
- dacSortByPos: "الترتيب حسب الموقع",
- dacSortByUrl: "الترتيب حسب الرابط",
- dacSortByName: "الترتيب حسب الاسم",
- reverse: "عكس الاختيار",
- dacUseIframe: "لتحميل المحتوى (بطيء) iframe استخدام",
- dacSaveAsZip: "zip حفظ كـ",
- dacSetCustomRule: "تعديل القواعد",
- dacAddUrl: "إضافة فصل",
- dacStartDownload: "تحميل المحدد",
- downloadShortcut: "تحميل الفصل",
- downloadSingleShortcut: "تحميل صفحة واحدة",
- downloadCustomShortcut: "تحميل مخصص"
+ encode: true,
+ fetch: "%D8%AA%D8%AD%D9%85%D9%8A%D9%84",
+ info: "%D8%A7%D9%84%D9%85%D8%B5%D8%AF%D8%B1:%20#t#%0A%D8%AA%D9%85%20%D8%AA%D9%86%D8%B2%D9%8A%D9%84%20%D8%A7%D9%84%D9%80%20TXT%20%D8%A8%D9%88%D8%A7%D8%B3%D8%B7%D8%A9%20'DownloadAllContent'",
+ error: "%D9%81%D8%B4%D9%84%20%D9%81%D9%8A%20%D8%AA%D8%AD%D9%85%D9%8A%D9%84%20%D8%A7%D9%84%D9%81%D8%B5%D9%84%20%D8%A7%D9%84%D8%AD%D8%A7%D9%84%D9%8A",
+ downloading: "......%25s%20%D8%AA%D8%AD%D9%85%D9%8A%D9%84%3Cbr%3E%D8%B5%D9%81%D8%AD%D8%A7%D8%AA%20%D9%85%D8%AA%D8%A8%D9%82%D9%8A%D8%A9%20%25s%20%D8%B5%D9%81%D8%AD%D8%A7%D8%AA%20%D8%AA%D9%85%20%D8%AA%D8%AD%D9%85%D9%8A%D9%84%D9%87%D8%A7%D8%8C%20%D9%87%D9%86%D8%A7%D9%83%20%25s",
+ complete: "%D8%B5%D9%81%D8%AD%D8%A7%D8%AA%20%D9%81%D9%8A%20%D8%A7%D9%84%D9%85%D8%AC%D9%85%D9%88%D8%B9%20%25s%20%D8%A7%D9%83%D8%AA%D9%85%D9%84!%20%D8%AD%D8%B5%D9%84%D8%AA%20%D8%B9%D9%84%D9%89",
+ del: "%D9%84%D8%AA%D8%AC%D8%A7%D9%87%D9%84%20CSS%20%D8%AA%D8%B9%D9%8A%D9%8A%D9%86%20%D9%85%D8%AD%D8%AF%D8%AF%D8%A7%D8%AA",
+ custom: "%D8%AA%D8%AD%D9%85%D9%8A%D9%84%20%D9%85%D8%AE%D8%B5%D8%B5",
+ customInfo: "%D9%84%D8%B1%D9%88%D8%A7%D8%A8%D8%B7%20%D8%A7%D9%84%D9%81%D8%B5%D9%88%D9%84%20sss%20%D8%A5%D8%AF%D8%AE%D8%A7%D9%84%20%D8%A7%D9%84%D8%B1%D9%88%D8%A7%D8%A8%D8%B7%20%D8%A3%D9%88%20%D9%85%D8%AD%D8%AF%D8%AF%D8%A7%D8%AA",
+ reSort: "%D8%A5%D8%B9%D8%A7%D8%AF%D8%A9%20%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D8%AD%D8%B3%D8%A8%20%D8%A7%D9%84%D8%B9%D9%86%D9%88%D8%A7%D9%86",
+ reSortUrl: "%D8%A5%D8%B9%D8%A7%D8%AF%D8%A9%20%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D8%AD%D8%B3%D8%A8%20%D8%A7%D9%84%D8%B1%D9%88%D8%A7%D8%A8%D8%B7",
+ setting: "%D9%81%D8%AA%D8%AD%20%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF%D8%A7%D8%AA",
+ searchRule: "%D9%82%D8%A7%D8%B9%D8%AF%D8%A9%20%D8%A7%D9%84%D8%A8%D8%AD%D8%AB",
+ abort: "%D8%A5%D9%8A%D9%82%D8%A7%D9%81",
+ save: "%D8%AD%D9%81%D8%B8",
+ saveAsMd: "Markdown%20%D8%AD%D9%81%D8%B8%20%D9%83%D9%80",
+ saveAsJSON: "JSON%20%D8%AD%D9%81%D8%B8%20%D9%83%D9%80",
+ downThreadNum: "%D8%AA%D8%B9%D9%8A%D9%8A%D9%86%20%D8%B9%D8%AF%D8%AF%20%D8%A7%D9%84%D8%AE%D9%8A%D9%88%D8%B7%20%D9%84%D9%84%D8%AA%D8%AD%D9%85%D9%8A%D9%84",
+ enableTouch: "On%20the%20mobile%20device,%20slide%20the%20screen%20in%20the%20direction%20of%20%E2%86%92%E2%86%93%E2%86%90%E2%86%91%20to%20draw%20a%20square%20will%20start%20downloading%20immediately",
+ customTitle: "%D8%AA%D8%AE%D8%B5%D9%8A%D8%B5%20%D8%B9%D9%86%D9%88%D8%A7%D9%86%20%D8%A7%D9%84%D9%81%D8%B5%D9%84%D8%8C%20%D8%A5%D8%AF%D8%AE%D8%A7%D9%84%20%D8%A7%D9%84%D9%85%D8%AD%D8%AF%D8%AF%20%D9%81%D9%8A%20%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9%20%D8%A7%D9%84%D8%AF%D8%A7%D8%AE%D9%84%D9%8A%D8%A9",
+ saveUrl: "%D8%AD%D9%81%D8%B8%20URL",
+ disableAutoStartSave: "%D8%AA%D8%B9%D8%B7%D9%8A%D9%84%20%D8%A7%D9%84%D8%AD%D9%81%D8%B8%20%D8%A7%D9%84%D8%AA%D9%84%D9%82%D8%A7%D8%A6%D9%8A",
+ maxDlPerMin: "%D8%A7%D9%84%D8%AD%D8%AF%20%D8%A7%D9%84%D8%A3%D9%82%D8%B5%D9%89%20%D9%84%D8%B9%D8%AF%D8%AF%20%D8%A7%D9%84%D8%AA%D9%86%D8%B2%D9%8A%D9%84%D8%A7%D8%AA%20%D9%81%D9%8A%20%D8%A7%D9%84%D8%AF%D9%82%D9%8A%D9%82%D8%A9",
+ reSortDefault: "%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D8%A7%D9%84%D8%A7%D9%81%D8%AA%D8%B1%D8%A7%D8%B6%D9%8A%20%D8%AD%D8%B3%D8%A8%20%D8%A7%D9%84%D9%85%D9%88%D9%82%D8%B9%20%D9%81%D9%8A%20%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9",
+ reverseOrder: "%D8%B9%D9%83%D8%B3%20%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D8%A7%D9%84%D9%81%D8%B5%D9%88%D9%84",
+ saveBtn: "%D8%AD%D9%81%D8%B8%20%D8%A7%D9%84%D8%A5%D8%B9%D8%AF%D8%A7%D8%AF%D8%A7%D8%AA",
+ saveOk: "%D8%AA%D9%85%20%D8%A7%D9%84%D8%AD%D9%81%D8%B8",
+ nextPage: "%D8%A7%D9%84%D8%AA%D8%AD%D9%82%D9%82%20%D9%85%D9%86%20%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A9%20%D8%A7%D9%84%D8%AA%D8%A7%D9%84%D9%8A%D8%A9%20%D9%81%D9%8A%20%D8%A7%D9%84%D9%81%D8%B5%D9%84",
+ nextPageReg: "%D9%85%D8%AE%D8%B5%D8%B5%20%D9%84%D9%84%D8%B5%D9%81%D8%AD%D8%A9%20%D8%A7%D9%84%D8%AA%D8%A7%D9%84%D9%8A%D8%A9%20RegExp",
+ retainImage: "%D8%A7%D9%84%D8%A7%D8%AD%D8%AA%D9%81%D8%A7%D8%B8%20%D8%A8%D8%B9%D9%86%D9%88%D8%A7%D9%86%20%D8%A7%D9%84%D8%B5%D9%88%D8%B1%D8%A9%20%D8%A5%D8%B0%D8%A7%20%D9%83%D8%A7%D9%86%D8%AA%20%D9%87%D9%86%D8%A7%D9%83%20%D8%B5%D9%88%D8%B1%20%D9%81%D9%8A%20%D8%A7%D9%84%D9%86%D8%B5",
+ minTxtLength: "%D8%A7%D9%84%D9%85%D8%AD%D8%A7%D9%88%D9%84%D8%A9%20%D9%85%D8%B1%D8%A9%20%D8%A3%D8%AE%D8%B1%D9%89%20%D8%B9%D9%86%D8%AF%D9%85%D8%A7%20%D9%8A%D9%83%D9%88%D9%86%20%D8%B7%D9%88%D9%84%20%D8%A7%D9%84%D9%85%D8%AD%D8%AA%D9%88%D9%89%20%D8%A3%D9%82%D9%84%20%D9%85%D9%86%20%D9%87%D8%B0%D8%A7",
+ showFilterList: "%D8%B9%D8%B1%D8%B6%20%D9%86%D8%A7%D9%81%D8%B0%D8%A9%20%D8%A7%D9%84%D8%AA%D8%B5%D9%81%D9%8A%D8%A9%20%D9%88%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D9%82%D8%A8%D9%84%20%D8%A7%D9%84%D8%AA%D8%AD%D9%85%D9%8A%D9%84",
+ ok: "%D9%85%D9%88%D8%A7%D9%81%D9%82",
+ close: "%D8%A5%D8%BA%D9%84%D8%A7%D9%82",
+ dacSortByPos: "%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D8%AD%D8%B3%D8%A8%20%D8%A7%D9%84%D9%85%D9%88%D9%82%D8%B9",
+ dacSortByUrl: "%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D8%AD%D8%B3%D8%A8%20%D8%A7%D9%84%D8%B1%D8%A7%D8%A8%D8%B7",
+ dacSortByName: "%D8%A7%D9%84%D8%AA%D8%B1%D8%AA%D9%8A%D8%A8%20%D8%AD%D8%B3%D8%A8%20%D8%A7%D9%84%D8%A7%D8%B3%D9%85",
+ reverse: "%D8%B9%D9%83%D8%B3%20%D8%A7%D9%84%D8%A7%D8%AE%D8%AA%D9%8A%D8%A7%D8%B1",
+ dacUseIframe: "%D9%84%D8%AA%D8%AD%D9%85%D9%8A%D9%84%20%D8%A7%D9%84%D9%85%D8%AD%D8%AA%D9%88%D9%89%20(%D8%A8%D8%B7%D9%8A%D8%A1)%20iframe%20%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85",
+ dacSaveAsZip: "zip%20%D8%AD%D9%81%D8%B8%20%D9%83%D9%80",
+ dacSetCustomRule: "%D8%AA%D8%B9%D8%AF%D9%8A%D9%84%20%D8%A7%D9%84%D9%82%D9%88%D8%A7%D8%B9%D8%AF",
+ dacAddUrl: "%D8%A5%D8%B6%D8%A7%D9%81%D8%A9%20%D9%81%D8%B5%D9%84",
+ prefix:"Prefix%20of%20chapter%20name",
+ dacStartDownload: "%D8%AA%D8%AD%D9%85%D9%8A%D9%84%20%D8%A7%D9%84%D9%85%D8%AD%D8%AF%D8%AF",
+ downloadShortcut: "%D8%AA%D8%AD%D9%85%D9%8A%D9%84%20%D8%A7%D9%84%D9%81%D8%B5%D9%84",
+ downloadSingleShortcut: "%D8%AA%D8%AD%D9%85%D9%8A%D9%84%20%D8%B5%D9%81%D8%AD%D8%A9%20%D9%88%D8%A7%D8%AD%D8%AF%D8%A9",
+ downloadCustomShortcut: "%D8%AA%D8%AD%D9%85%D9%8A%D9%84%20%D9%85%D8%AE%D8%B5%D8%B5"
+ };
+ break;
+ case "ja":
+ case "ja-JP":
+ i18n={
+ fetch:"小説のダウンロードを開始",
+ info:"提供元:#t#\nこの作品は、怠惰小説ダウンローダー(DownloadAllContent)を使ってダウンロードされました。",
+ error:"このコンテンツの取得に失敗しました",
+ downloading:"%s/%sエピソードをダウンロード済み %sをダウンロード中",
+ complete:"全%sエピソードのダウンロードが完了しました",
+ del:"テキストの乱れを削除するCSSセレクターを設定",
+ custom:"カスタムルールでダウンロード",
+ customInfo:"URLまたは章のCSSセレクターを入力してください",
+ reSort:"章をタイトル順で並べ替え",
+ reSortUrl:"章をURL順で並べ替え",
+ setting:"オプション設定",
+ searchRule:"サイトの検索ルール",
+ abort:"この章をスキップ",
+ save:"現在の設定を保存",
+ saveAsMd:"Markdown形式で保存",
+ saveAsJSON: "JSON形式で保存",
+ downThreadNum:"同時ダウンロードスレッド数を設定(負の値はシングルスレッドでのダウンロード間隔)",
+ enableTouch:"モバイルで画面をスライドして正方形を描くとダウンロードを開始",
+ customTitle:"カスタム章タイトル(ページ内のテキストに対応するセレクターを入力)",
+ saveUrl: "URLを保存",
+ disableAutoStartSave: "自動保存を無効にする",
+ maxDlPerMin:"1分あたりの最大ダウンロード数",
+ reSortDefault:"デフォルト(ページ内の位置)で章を並べ替え",
+ reverseOrder:"章の並び順を反転",
+ saveBtn:"設定を保存",
+ saveOk:"保存しました",
+ nextPage:"章内のページを検出",
+ nextPageReg:"カスタムページネーション正規表現",
+ retainImage:"本文中の画像のURLを保持",
+ minTxtLength:"検出された本文の文字数がこの数より少ない場合、再取得を試行",
+ showFilterList:"ダウンロード前に章のフィルタリング・並べ替えウィンドウを表示",
+ ok:"OK",
+ close:"閉じる",
+ dacSortByPos:"ページ内の位置で並べ替え",
+ dacSortByUrl:"URLで並べ替え",
+ dacSortByName:"章の名前で並べ替え",
+ reverse:"選択を反転",
+ dacUseIframe:"iframeを使ってコンテンツをバックグラウンドで読み込む(低速)",
+ dacSaveAsZip:"Zip形式でダウンロード",
+ dacSetCustomRule:"ルールを編集",
+ dacAddUrl:"章を追加",
+ prefix:"章のタイトルにプレフィックスを追加",
+ dacStartDownload:"選択した章をダウンロード",
+ downloadShortcut:"章ダウンロードのショートカット",
+ downloadSingleShortcut:"単一ページダウンロードのショートカット",
+ downloadCustomShortcut:"カスタムダウンロードのショートカット"
};
break;
default:
@@ -395,8 +465,13 @@ if (window.top != window.self) {
abort:"Abort",
save:"Save",
saveAsMd:"Save as Markdown",
- downThreadNum:"Set threadNum for download",
+ saveAsJSON: "Save as JSON",
+ downThreadNum:"Set threadNum for download, negative means interval of single thread",
+ enableTouch:"On the mobile device, slide the screen in the direction of →↓←↑ to draw a square will start downloading immediately",
customTitle: "Customize the chapter title, enter the selector on inner page",
+ saveUrl: "Save URL",
+ disableAutoStartSave: "Disable auto save",
+ maxDlPerMin:"Maximum number of downloads per minute",
reSortDefault: "Default sort by position in the page",
reverseOrder:"Reverse chapter ordering",
saveBtn:"Save Setting",
@@ -416,15 +491,23 @@ if (window.top != window.self) {
dacSaveAsZip: "Save as zip",
dacSetCustomRule:"Modify rules",
dacAddUrl:"Add Chapter",
+ prefix:"Prefix of chapter name",
dacStartDownload:"Download selected",
- downloadShortcut:"Download chapter",
- downloadSingleShortcut:"Download single page",
- downloadCustomShortcut:"Custom download"
+ downloadShortcut:"Download chapter Shortcut",
+ downloadSingleShortcut:"Download single page Shortcut",
+ downloadCustomShortcut:"Custom download Shortcut"
};
break;
}
+ if (i18n.encode) {
+ for (let k in i18n) {
+ if (k != "encode") {
+ i18n[k] = decodeURI(i18n[k]);
+ }
+ }
+ }
var firefox=navigator.userAgent.toLowerCase().indexOf('firefox')!=-1,curRequests=[],useIframe=false,iframeSandbox=false,iframeInit=false;
- var filterListContainer,txtDownContent,txtDownWords,txtDownQuit,dacLinksCon,dacUseIframe,shadowContainer;
+ var filterListContainer,txtDownContent,txtDownWords,txtDownQuit,dacLinksCon,dacUseIframe,shadowContainer,downTxtShadowContainer;
const escapeHTMLPolicy = (win.trustedTypes && win.trustedTypes.createPolicy) ? win.trustedTypes.createPolicy('dac_default', {
createHTML: (string, sink) => string
@@ -511,7 +594,7 @@ if (window.top != window.self) {
filterListContainer = document.createElement("div");
filterListContainer.id = "filterListContainer";
filterListContainer.innerHTML = createHTML(`
-
+
-
+
${i18n.dacUseIframe} ${i18n.dacSaveAsZip}
@@ -534,7 +617,7 @@ if (window.top != window.self) {
-
+
`);
let dacSortByPos = filterListContainer.querySelector("#dacSortByPos");
let dacSortByUrl = filterListContainer.querySelector("#dacSortByUrl");
@@ -767,7 +850,7 @@ if (window.top != window.self) {
left: 50%;
top: 10%;
margin-left: -300px;
- z-index: 99998;
+ z-index: 2147483646;
background-color: #ffffff;
border: 1px solid #afb3b6;
border-radius: 10px;
@@ -784,6 +867,7 @@ if (window.top != window.self) {
`);
dacLinksCon = filterListContainer.querySelector("#dacLinksCon");
shadowContainer = document.createElement("div");
+ shadowContainer.id = "download-all-content";
document.body.appendChild(shadowContainer);
let shadow = shadowContainer.attachShadow({ mode: "open" });
shadow.appendChild(listStyle);
@@ -801,27 +885,28 @@ if (window.top != window.self) {
function initTxtDownDiv() {
if (txtDownContent) {
txtDownContent.style.display = "";
+ document.body.appendChild(downTxtShadowContainer);
return;
}
txtDownContent = document.createElement("div");
txtDownContent.id = "txtDownContent";
- let shadowContainer = document.createElement("div");
- document.body.appendChild(shadowContainer);
- let shadow = shadowContainer.attachShadow({ mode: "open" });
+ downTxtShadowContainer = document.createElement("div");
+ document.body.appendChild(downTxtShadowContainer);
+ let shadow = downTxtShadowContainer.attachShadow({ mode: "open" });
shadow.appendChild(txtDownContent);
- txtDownContent.innerHTML=createHTML(`
+ txtDownContent.innerHTML = createHTML(`
')",
@@ -767,8 +689,8 @@
{
"name": "优酷漫画手機版 - 閱讀",
"author": "skofkyo",
- "example": "http://h5.ykmh.com/manhua/DrSTONEshijiyuan/2456.html",
- "url": "^https?://h5\\.ykmh\\.com/manhua/[a-z]+/\\d+\\.html",
+ "example": "http://m.ykmh.net/manhua/DrSTONEshijiyuan/2456.html",
+ "url": "^https?://m\\.ykmh\\.net/manhua/[a-z]+/\\d+\\.html",
"history": 2,
"pinUrl": true,
"init": "$('#images').unbind('click',SinTheme.nextPage);$('#images').unbind('mousedown');let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/chapterImages/)>-1).innerHTML;let imgs=eval(code.match(/chapterImages[^;]+/)[0]);let host=eval(code.match(/pageImage[^;]+/)[0]).match(/^https?:\\/\\/[^/]+/)[0];let F=new DocumentFragment();imgs.forEach(e=>{let img=new Image();img.src=host+e;F.appendChild(img)});let E=document.querySelector('#images');E.innerHTML='';E.appendChild(F);",
@@ -784,8 +706,8 @@
{
"name": "优酷漫画 - PC版閱讀",
"author": "skofkyo",
- "example": "http://www.ykmh.com/manhua/DrSTONEshijiyuan/2457.html",
- "url": "^https?://www\\.ykmh\\.com/manhua/[a-z]+/\\d+\\.html",
+ "example": "http://www.ykmh.net/manhua/DrSTONEshijiyuan/2457.html",
+ "url": "^https?://www\\.ykmh\\.net/manhua/[a-z]+/\\d+\\.html",
"history": 2,
"pinUrl": true,
"init": "let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/chapterImages/)>-1).innerHTML;let imghost=eval(code.match(/pageImage[^;]+/)[0]).match(/^https?:\\/\\/[^/]+\\//)[0];let imgData=eval(code.match(/chapterImages[^;]+/)[0]);let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src=imghost+e;F.appendChild(img)});let E=document.querySelector('#images');E.innerHTML='';E.appendChild(F);",
@@ -831,52 +753,6 @@
"pageBarText": "let t=doc.querySelector('.head_wz');if(t)return t.innerHTML.replace(/.+;/,'')",
"css": ".nav-pagination,.img_land_prev,.img_land_next,#page_select,.img_info,.title.pr>em:nth-child(5),.title.pr>span,.block.clearfix{display:none!important}#images>img{max-width: 100% !important;display: block !important;margin: 0 auto -2px auto !important;border:0px!important;padding:0px!important;}body,.autoHeight,.wrap_last_mid .pre,.wrap_last_mid .next,.chapter-view .panel,.mainNav_inner{width:auto!important;min-width:auto!important}"
},
-{
- "name": "亲亲漫画 - 手機版漫畫在新分頁打開",
- "author": "skofkyo",
- "example": "https://m.acgvd.com/update/",
- "url": "^https?://m\\.acg(w|u|q|v)d\\.com/(update|list|list/wanjie)?/?$",
- "pinUrl": true,
- "init": "let openInNewTab=()=>document.querySelectorAll('.itemBox a:not([target=_blank]),.list-comic a:not([target=_blank])').forEach(a=>{a.setAttribute('target','_blank')});openInNewTab();new MutationObserver(()=>{openInNewTab()}).observe(document.body,{childList:true,subtree:true});"
-},
-{
- "name": "亲亲漫画 - 手機版閱讀",
- "author": "skofkyo",
- "example": "https://m.acgvd.com/manhua/39305/1277010.html",
- "url": "^https?://m\\.acg(w|u|q|v)d\\.com/manhua/\\d+/\\d+\\.html",
- "pinUrl": true,
- "history": 2,
- "init": "let ge=e=>document.querySelector(e);$('.control_bottom').append('');let imgs=document.createElement('div');imgs.className='PagetualImgBox';let host=SinConf.resHost[0].domain+'/';let F=new DocumentFragment();chapterImages.forEach(e=>{let img=new Image();img.src=host+chapterPath+e;F.appendChild(img)});imgs.appendChild(F);let x=ge('#loading');x.parentNode.insertBefore(imgs,x);ge('a.iconRet').href=comicUrl;let n=ge('#action li:nth-child(4)>a');if(nextChapterData.id==null){n.href=comicUrl;n.innerText='返回目录'}",
- "nextLinkByJs": "let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/nextChapterData/)>-1).innerHTML;let next=eval(code.match(/nextChapterData[^;]+/)[0]);if(next.id>0)return next.url",
- "pageElement": "//script[contains(text(),'chapterImages')]",
- "replaceElement": "head>title,.BarTit",
- "insert": "#loading",
- "insertPos": 1,
- "pageInit": "let ge=e=>document.querySelector(e);let code=Array.from(doc.scripts).find(s=>s.innerHTML.search(/chapterImages/)>-1).innerHTML;let s=document.createElement('script');s.textContent=code;let x=document.querySelector('#loading');x.parentNode.insertBefore(s,x);let cd=eval(code.match(/comicUrl[^;]+/)[0]);let pd=eval(code.match(/prevChapterData[^;]+/)[0]);let nd=eval(code.match(/nextChapterData[^;]+/)[0]);let p=ge('#action li:nth-child(1)>a');let n=ge('#action li:nth-child(4)>a');if(nd.id>0){n.href=nd.uri;n.innerText='下一章'}else{n.href=cd;n.innerText='返回目录'}p.href=pd.uri;",
- "pageAction": "jmzz20191018();let imgs=document.createElement('div');imgs.className='PagetualImgBox';let host=SinConf.resHost[0].domain+'/';let F=new DocumentFragment();chapterImages.forEach(e=>{let img=new Image();img.src=host+chapterPath+e;F.appendChild(img)});imgs.appendChild(F);let x=document.querySelector('#loading');x.parentNode.insertBefore(imgs,x);let gae=e=>document.querySelectorAll(e);let ps=gae('.pagetual_pageBar');if(ps.length>4){ps[0].remove();let ds=gae('#images~*');for(let i in ds){if(/pagetual/.test(ds[i].id)){break};ds[i].remove()}}",
- "pageBarText": "let t=doc.querySelector('.BarTit');if(t)return t.innerText.match(/[^(]+/)[0];",
- "sleep": 1000,
- "css": "#page-info,#action li:nth-child(2),#action li:nth-child(3),.control_bottom~*,.chapter-view~*,#images{display:none!important}#action li{width:50%!important}.chapter-view img{width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}.side_public{opacity:0.4;border-radius: 50%;position:fixed;bottom:60px;right:13px;width:36px;height:35px;display:none;margin-left:20px}.side_public a{border-radius: 50%;display:inline-block;*zoom:1;*display:inline;width:36px;height:36px;border:1px solid #e6e6e6;}.side_public a.return-top{background:#fff url(https://www.acgqd.com/assets/4155373f/images/side_ico.png) no-repeat 2px -81px}"
-},
-{
- "name": "亲亲漫画 - PC版閱讀",
- "author": "skofkyo",
- "example": "http://www.acgvd.com/manhua/39305/1277010.html",
- "url": "^https?://www\\.acg(w|u|q|v)d\\.com/manhua/\\d+/\\d+\\.html",
- "pinUrl": true,
- "history": 2,
- "init": "let imgs=document.createElement('div');imgs.className='PagetualImgBox';let host=SinConf.resHost[0].domain+'/';let F=new DocumentFragment();chapterImages.forEach(e=>{let img=new Image();img.src=host+chapterPath+e;F.appendChild(img)});imgs.appendChild(F);document.querySelector('.comic_wraCon').appendChild(imgs);",
- "nextLink": "span.next>a",
- "pageElement": "//script[contains(text(),'chapterImages')]",
- "replaceElement": "head>title,.wrap_last_head,.wrap_last_mid,.btmBtnBox",
- "insert": ".comic_wraCon",
- "insertPos": 2,
- "pageInit": "let code = Array.from(doc.scripts).find(s=>s.innerHTML.search(/chapterImages/)>-1).innerHTML;document.querySelector('.comic_wraCon').appendChild(document.createElement('script')).textContent = code;",
- "pageAction": "jmzz20191018();let imgs=document.createElement('div');imgs.className='PagetualImgBox';let host=SinConf.resHost[0].domain+'/';let F=new DocumentFragment();chapterImages.forEach(e=>{let img=new Image();img.src=host+chapterPath+e;F.appendChild(img)});imgs.appendChild(F);document.querySelector('.comic_wraCon').appendChild(imgs);let gae=e=>document.querySelectorAll(e);let ps=gae('.pagetual_pageBar');if(ps.length>4){ps[0].remove();let ds=gae('#images~*');for(let i in ds){if(/pagetual/.test(ds[i].id)){break};ds[i].remove()}}",
- "pageBarText": "let t=doc.querySelector('h2');if(t)return t.innerText;",
- "sleep": 1000,
- "css": ".comic_wraCon img{border:none!important;padding:0!important;width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}select,.img_land_prev,.img_land_next,#images{display:none!important}body,.autoHeight,.wrap_last_mid .pre,.wrap_last_mid .next,.chapter-view .panel,.mainNav_inner{width:auto!important;min-width:auto!important}"
-},
{
"name": "古风漫画网 / 优酷漫画 / 亲亲漫画 / 漫画456 - 分類",
"author": "skofkyo",
@@ -942,8 +818,8 @@
{
"name": "漫画160 - 手機版閱讀",
"author": "skofkyo",
- "example": "https://m.mh160.cc/kanmanhua/yuanlaiwoshixianjiezhizun/1689580801.html",
- "url": "^https?://m\\.mh160\\.cc/kanmanhua/\\w+/\\d+\\.html",
+ "example": "https://m.mh160mh.com/kanmanhua/yuanlaiwoshixianjiezhizun/1689580801.html",
+ "url": "^https?://m\\.mh160mh\\.com/kanmanhua/\\w+/\\d+\\.html",
"pinUrl": true,
"history": 2,
"init": "let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/qTcms_S_m_murl_e/)>-1).innerHTML;let imgBase64=code.match(/qTcms_S_m_murl_e=([^;]+)/)[1].replaceAll('\"','');let imgData=base64_decode(imgBase64).split('$qingtiandy$');let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src=f_qTcms_Pic_curUrl_realpic(e);F.appendChild(img)});let E=document.querySelector('#commicBox');E.innerHTML='';E.appendChild(F);",
@@ -959,8 +835,8 @@
{
"name": "漫画160 - PC版閱讀",
"author": "skofkyo",
- "example": "https://www.mh160.cc/kanmanhua/tianqiyubao/1668716868.html",
- "url": "^https?://www\\.mh160\\.cc/kanmanhua/\\w+/\\d+\\.html",
+ "example": "https://www.mh160mh.com/kanmanhua/tianqiyubao/1668716868.html",
+ "url": "^https?://www\\.mh160mh\\.com/kanmanhua/\\w+/\\d+\\.html",
"pinUrl": true,
"history": 2,
"init": "let code=Array.from(document.scripts).find(s=>s.innerHTML.search(/qTcms_S_m_murl_e/)>-1).innerHTML;let imgBase64=code.match(/qTcms_S_m_murl_e=([^;]+)/)[1].replaceAll('\"','');let imgData=base64_decode(imgBase64).split('$qingtiandy$');let F=new DocumentFragment();imgData.forEach(e=>{let img=new Image();img.src=f_qTcms_Pic_curUrl_realpic(e);F.appendChild(img)});let E=document.querySelector('#qTcms_Pic_middle').parentNode;E.innerHTML='';E.appendChild(F);",
@@ -976,8 +852,8 @@
{
"name": "漫画160 - 分類",
"author": "skofkyo",
- "example": "www.mh160.cc",
- "url": "^https?://www\\.mh160\\.cc/",
+ "example": "www.mh160mh.com",
+ "url": "^https?://www\\.mh160mh\\.com/",
"nextLink": "//a[text()='下一页'] | //li[a[@class='active']]/following-sibling::li[1]/a",
"pageElement": ".cy_list_r,.grid-row.clearfix,#dmList,#contList,[class^='bookList'],.mh-search-list",
"replaceElement": ".NewPages,.pager,.page_moreDiv",
@@ -1115,8 +991,7 @@
"init": "let ia = document.querySelector('input~a');let sa = document.querySelector('script[language]+a');if(ia){ia.removeAttribute('href');}else{sa.removeAttribute('href');}",
"nextLink": "//a[./img[@src='/images/d.gif']][not(@href='/exit/exit.htm')] | //a[span[text()='下一页']][not(@href='/exit/exit.htm')]",
"pageElement": "//script[@language]/following-sibling::a/img[@src][not(contains(@src,'.gif'))]",
- "replaceElement": "//a[./img[@src='/images/d.gif']] | //a[./img[@src='/images/t.gif']] | //div[@class='bottom']/ul[@class='subNav'] | //li[@class='txtA']",
- "pageBar": 0
+ "replaceElement": "//a[./img[@src='/images/d.gif']] | //a[./img[@src='/images/t.gif']] | //div[@class='bottom']/ul[@class='subNav'] | //li[@class='txtA']"
},
{
"name": "漫漫聚 / KuKu动漫 - 分類",
@@ -1200,7 +1075,7 @@
"css": ".ds,.adv-img,.page-index__btn{display:none!important}.rd-article-wr>img{width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}"
},
{
- "name": "好漫 6 / 漫客栈 / 漫画屋 - 分類",
+ "name": "漫客栈 / 漫画屋 - 分類",
"author": "skofkyo",
"example": "https://www.mkzhan.com/category/,https://www.mhua5.com/category/",
"url": "^https?://(www\\.)?(mkzhan|mhua5)\\.com/((category|search)|index\\.php/(category|search))",
@@ -1369,20 +1244,11 @@
"insertPos": 1,
"css": ".pagetual_pageBar{margin-top:10px!important}.pagetual_pageBar+.subitem{margin-top:-2px!important}"
},
-{
- "name": "字幕库 zmk",
- "author": "skofkyo",
- "example": "https://zimuku.org/",
- "url": "^https?://zimuku\\.org/",
- "nextLink": "a.next",
- "pageElement": "table>tbody",
- "replaceElement": ".pagination"
-},
{
"name": "點點字幕",
"author": "skofkyo",
- "example": "http://www.ddzimu.com/download/xslist.php?key=king",
- "url": "^https?://www\\.ddzimu\\.com/\\w+/xslist\\.php",
+ "example": "http://www.samfunny.com/download/xslist.php?key=king",
+ "url": "^https?://www\\.samfunny\\.com/\\w+/xslist\\.php",
"nextLink": "li.disabled+li>a",
"pageElement": ".list>ul>li:not(.first)",
"replaceElement": "div.pagination"
@@ -1450,25 +1316,6 @@
"replaceElement": ".pages.clear",
"rate": 3
},
-{
- "name": "言耽社 - 閱讀",
- "author": "skofkyo",
- "example": "https://yandanshe.com/",
- "url": "^https?://yandanshe\\.com/\\d+",
- "nextLink": "span.current+a",
- "pageElement": "title,.article-content",
- "replaceElement": ".list",
- "pageBarText": "let t=doc.querySelector('.article-content');if(t)return t.innerText"
-},
-{
- "name": "言耽社 - 分类页",
- "author": "skofkyo",
- "example": "https://yandanshe.com/",
- "url": "^https?://yandanshe\\.com/",
- "nextLink": ".next-page>a",
- "pageElement": ".excerpts",
- "replaceElement": ".pagination"
-},
{
"name": "MINI4K",
"author": "skofkyo",
@@ -1489,25 +1336,6 @@
"replaceElement": ".tsc_pagination",
"css": "#social_popup{display:none!important}.pagetual_pageBar{margin-top:0px!important}"
},
-{
- "name": "TorrentGalaxy",
- "author": "skofkyo",
- "example": "https://torrentgalaxy.to/torrents.php",
- "url": "^https?://torrentgalaxy\\.to/",
- "nextLink": "li.page-item.active+li.page-item>a",
- "pageElement": ".tgxtable>.tgxtablerow",
- "replaceElement": ".pagination"
-},
-{
- "name": "kickasss",
- "author": "skofkyo",
- "example": "https://kickasss.to/",
- "url": "^https?://(kickasss|katcr)\\.",
- "action": 1,
- "nextLink": "a.active+a",
- "pageElement": "table.data.frontPageWidget>tbody>tr:not(.firstr)",
- "replaceElement": ".pages"
-},
{
"name": "1337x",
"author": "skofkyo",
@@ -1575,28 +1403,6 @@
"nextLink": "a.next",
"pageElement": "#table-list>tbody>tr"
},
-{
- "name": "怡萱动漫",
- "author": "skofkyo",
- "example": "https://www.iyxdm.me/resource/",
- "url": "^https?://www\\.iyxdm\\.me/",
- "nextLink": "//a[@class='nextPage' or text()='下一页']",
- "pageElement": ".dhnew>ul",
- "replaceElement": ".pagelist"
-},
-{
- "name": "LIBVIO",
- "author": "skofkyo",
- "example": "https://www.libviohd.com/type/1.html",
- "url": "^https?://www\\.libviohd\\.com/",
- "action": 1,
- "wait": 1000,
- "nextLink": "li.active+li>a",
- "pageElement": ".stui-vodlist",
- "replaceElement": ".stui-page__item",
- "pageInit": "let defaultImg='https://vkceyugu.cdn.bspapp.com/VKCEYUGU-ae4eabf5-1b15-425e-bdc9-144e48cded99/c9d2141e-8569-4996-9c73-d633a0669fa8.gif';doc.querySelectorAll('a.lazyload').forEach((item)=>{let imgUrl=item.dataset.original;let image=new Image();image.src=imgUrl;if(!image.complete){item.style.backgroundImage=`url(${defaultImg})`}})",
- "css": ".stui-page__all{display:none!important}"
-},
{
"name": "筆趣影視",
"author": "skofkyo",
@@ -1622,16 +1428,6 @@
"pageElement": "//tr[td[@nowrap]]",
"replaceElement": "//div[contains(@class,'paginator')] | //table[tbody/tr/td/font[@color]]"
},
-{
- "name": "99images",
- "author": "skofkyo",
- "example": "https://99images.com/celebrities/aisha-sharma",
- "url": "^https?://99images\\.com/",
- "action": 1,
- "nextLink": "a[rel='next']",
- "pageElement": "//div[@class='w-full columns-2 md:columns-3 lg:columns-4 xl:columns-5 self-start px-4']",
- "replaceElement": "//div[nav]"
-},
{
"name": "steamcommunity.com",
"author": "skofkyo",
@@ -1687,27 +1483,6 @@
"replaceElement": ".pagination",
"css": ".pagetual_pageBar{margin-top:0px!important}"
},
-{
- "name": "电影狗",
- "author": "skofkyo",
- "example": "https://www.dianyinggou.com/yingku/",
- "url": "^https?://www\\.dianyinggou\\.com/",
- "nextLink": ".mainPage li.selected+li>a",
- "pageElement": ".movies,.celebrity,.cntBox.articles",
- "replaceElement": ".mainPage ",
- "lazyImgSrc": "data-url",
- "css": ".movies+.pagetual_pageBar,.celebrity+.pagetual_pageBar{margin-top:-40px!important}"
-},
-{
- "name": "厂长资源",
- "author": "skofkyo",
- "example": "https://www.czys.top/movie_bt",
- "url": "^https?://[^/]+/",
- "include": "//title[contains(text(),'厂长资源')]",
- "nextLink": ".current+a",
- "pageElement": ".bt_img>ul",
- "replaceElement": ".pagenavi_txt"
-},
{
"name": "NO视频",
"author": "skofkyo",
@@ -1737,20 +1512,6 @@
"pageElement": "//div[article]",
"replaceElement": "#pagination"
},
-{
- "name": "www.thingiverse.com",
- "author": "skofkyo",
- "example": "https://www.thingiverse.com/",
- "url": "^https?://www\\.thingiverse\\.com/",
- "action": 1,
- "waitElement": [
- "[class^='ItemCardContentWrapper']>[class^='Image__image'][src^='http']"
- ],
- "nextLink": "a[aria-label='Next page']",
- "pageElement": "[class^='ItemCardGrid__itemCardGrid']",
- "replaceElement": "div[class^='Pagination__pagination'].margin-top--md",
- "css": ".pagetual_pageBar{margin-top:2px!important;margin-bottom:0px!important}"
-},
{
"name": "https://www.orcy.net.cn/",
"author": "skofkyo",
@@ -1797,16 +1558,6 @@
"replaceElement": ".pagination",
"rate": 3
},
-{
- "name": "cahdroid",
- "author": "skofkyo",
- "example": "https://cahdroid.com/",
- "url": "^https?://cahdroid\\.com/",
- "include": ".pagination",
- "nextLink": "span.page-numbers.current+a",
- "pageElement": ".relat,.post-show",
- "replaceElement": ".pagination"
-},
{
"name": "docs.oracle.com",
"author": "skofkyo",
@@ -1890,10 +1641,10 @@
"replaceElement": ".pagination"
},
{
- "name": "億破姐&電腦系統吧",
+ "name": "億破姐",
"author": "skofkyo",
- "example": "https://www.ypojie.com/pc,http://www.dnxitong.com/soft/",
- "url": "^https?://www\\.(ypojie|dnxitong)\\.com/",
+ "example": "https://www.ypojie.com/pc",
+ "url": "^https?://www\\.ypojie\\.com/",
"nextLink": ".next-page>a",
"pageElement": "article[class^='excerpt excerpt-']",
"replaceElement": ".pagination",
@@ -1907,7 +1658,7 @@
"nextLink": "a.next",
"pageElement": "article[class^='post']",
"replaceElement": ".pagination",
- "pageInit": "doc.querySelectorAll('a.img-holder').forEach(a=>{a.style.backgroundImage=`url('${a.dataset.src}')`;a.classList.add('b-loaded');a.removeAttribute('data-src')})"
+ "pageInit": "doc.querySelectorAll('a.img-holder[data-src]').forEach(a=>{a.style.backgroundImage=`url('${a.dataset.src}')`;a.classList.add('b-loaded');a.removeAttribute('data-src')})"
},
{
"name": "KaranPc",
@@ -1936,16 +1687,6 @@
"url": "^https?://apkpure\\.com/",
"loadMore": "a.show-more"
},
-{
- "name": "軟體部落",
- "author": "skofkyo",
- "example": "https://softblog.tw/green-portable",
- "url": "^https?://softblog\\.tw/",
- "include": ".page-numbers",
- "nextLink": "a.next",
- "pageElement": "#blog-entries",
- "replaceElement": ".oceanwp-pagination.clr"
-},
{
"name": "Gdaily",
"author": "skofkyo",
@@ -2033,205 +1774,6 @@
"pageElement": "//div[div[@class='thumbnail']]",
"replaceElement": "#pagination"
},
-{
- "name": "448人体艺术",
- "author": "skofkyo",
- "example": "https://488xm.com/666rentiyishu/",
- "url": "^https?://488xm\\.com/\\w+/",
- "pageElement": "#container>.grid",
- "replaceElement": ".pagelist"
-},
-{
- "name": "gogo人体艺术 - 圖片",
- "author": "skofkyo",
- "example": "https://gogortrt.com/gmgqdd/1305/",
- "url": "^https?://gogortrt\\.[a-z]{2,3}/[a-z]+/\\d+/",
- "init": "let a=document.querySelector('.main>div:not(.atc_new_head)>a');a.outerHTML=a.innerHTML;",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".main>div:not(.atc_new_head):not(.keywords) img[alt]",
- "replaceElement": ".Mrlsr55,.RlpeZsp,.cgdijkn,.d70rZyL,.i09cWt8,.pages,.pfb45A1,.vd7O8HI,.wpwRCvy,.zrLIsoJ",
- "pageBar": 0
-},
-{
- "name": "gogo人体艺术",
- "author": "skofkyo",
- "example": "https://gogortrt.com/gmgqdd/",
- "url": "^https?://gogortrt\\.[a-z]{2,3}/[a-z]+/",
- "include": ".index_list",
- "nextLink": "//a[text()='下一页' and contains(@href,'html')]",
- "pageElement": ".ulPic",
- "replaceElement": ".pages",
- "css": "iframe{height:55px!important}"
-},
-{
- "name": "956体艺术 - 圖片",
- "author": "skofkyo",
- "example": "https://956n.com/rbddszysz/1398/",
- "url": "^https?://956[a-z]{1,2}\\.[a-z]{2,3}/[a-z]+/\\d+/(\\d+\\.html$)?",
- "init": "document.querySelectorAll('.content>a').forEach(a=>{a.outerHTML=a.innerHTML})",
- "nextLink": "//a[text()='下一页' and contains(@href,'html')]",
- "pageElement": ".content img[alt]",
- "replaceElement": ".page",
- "pageBar": 0
-},
-{
- "name": "956人体艺术",
- "author": "skofkyo",
- "example": "https://956n.com/rbddszysz/",
- "url": "^https?://956[a-z]{1,2}\\.[a-z]{2,3}/",
- "exclude": ".title",
- "nextLink": "//a[text()='下一页' and contains(@href,'html')]",
- "pageElement": "//ul[li/a/@title]",
- "replaceElement": ".page",
- "css": ".pagetual_pageBar{margin-top:0px!important;margin-bottom:0px!important}"
-},
-{
- "name": "666人体艺术 - 圖片",
- "author": "skofkyo",
- "example": "https://6666rt.com/ArtZG/2152/1.html",
- "url": "^https?://[6]{3,4}[a-z]{2}\\.[a-z]{2,3}/[a-zA-Z]+/\\d+/\\d+\\.html",
- "init": "document.querySelectorAll('.imgbox>a').forEach(a=>{a.outerHTML=a.innerHTML})",
- "nextLink": "//a[text()='下一页 >>' and contains(@href,'html')]",
- "pageElement": ".imgbox img[alt]",
- "replaceElement": ".page,span>h1,.www",
- "pageBar": 0,
- "css": "img[alt]{margin-top:0px!important;margin-bottom:0px!important}.dis{display:none!important}"
-},
-{
- "name": "666人体艺术",
- "author": "skofkyo",
- "example": "https://6666rt.com/ArtZG/",
- "url": "^https?://[6]{3,4}[a-z]{2}\\.[a-z]{2,3}/",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".tpm02>.fzltp>ul",
- "replaceElement": ".pagelist"
-},
-{
- "name": "36人体艺术 - 圖片",
- "author": "skofkyo",
- "example": "www.36ut.com,xixirt.org",
- "url": "^https?://(www\\.)?(36[a-z]{2}|xixirt)\\.[a-z]{2,3}/[a-z]+/(\\d+/|\\d+(_\\d+)?\\.html)",
- "action": 1,
- "init": "let a=document.querySelector('.pp>a');a.outerHTML=a.innerHTML;",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".pp img",
- "replaceElement": ".page-show",
- "pageBar": 0,
- "css": ".picTip{display:none!important}"
-},
-{
- "name": "36人体艺术",
- "author": "skofkyo",
- "example": "www.36ut.com,xixirt.org",
- "url": "^https?://(www\\.)?(36[a-z]{2}|xixirt)\\.[a-z]{2,3}/",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".detail-list",
- "replaceElement": ".page-show",
- "css": ".pagetual_pageBar{margin-top:-10px!important}"
-},
-{
- "name": "AJ人体艺术 - 圖片",
- "author": "skofkyo",
- "example": "https://www.02aj.com/yzrt/8674.html",
- "url": "^https?://www\\.02aj\\.[a-z]{2,3}/[a-z]+/\\d+(_\\d+)?\\.html",
- "action": 1,
- "init": "document.querySelectorAll('.content>a').forEach(a=>{a.outerHTML=a.innerHTML})",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".content img",
- "replaceElement": ".paging",
- "pageBar": 0,
- "css": "img[alt]{margin-bottom:0px!important}"
-},
-{
- "name": "AJ人体艺术",
- "author": "skofkyo",
- "example": "https://www.02aj.com/yzrt/",
- "url": "^https?://www\\.\\d+aj\\.[a-z]{2,3}/",
- "nextLink": "//a[text()='下一页']",
- "pageElement": "//div[(div/div/a/img/@alt) and @class='list']",
- "replaceElement": ".page-list",
- "css": ".pagetual_pageBar{margin-top:-10px!important}"
-},
-{
- "name": "139人体艺术手機版 - 圖片",
- "author": "skofkyo",
- "example": "https://m.139tu.com/rtysyz/20200710/7479.html",
- "url": "^https?://(m|wap)\\.([0-9]{2,4}[a-z]{1,5}|[a-z]{2,5}[0-9]{1,3}|\\d+aj|\\d+|xixirt|gogortrt|7m11)\\.[a-z]{2,3}/[a-zA-Z]+/(\\d+/(\\d+\\.html$)?|\\d+(_\\d+)?\\.html$|\\d+/\\d+(_\\d+)?\\.html$)",
- "init": "document.querySelectorAll('.tal>a').forEach(a=>{a.outerHTML=a.innerHTML})",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".tal img[alt]",
- "replaceElement": ".page,body>[style='font-size:14px;'],.tip",
- "pageBar": 0,
- "css": "[style='margin:3px 0 0 0;']{display:none!important}img[alt]{opacity: 1!important}"
-},
-{
- "name": "139人体艺术手機版",
- "author": "skofkyo",
- "example": "88rtys.com,https://m.139tu.com/rtysyz/",
- "url": "^https?://(m|wap)\\.([0-9]{2,4}[a-z]{1,5}|[a-z]{2,5}[0-9]{1,3}|\\d+aj|\\d+|xixirt|gogortrt|7m11)\\.[a-z]{2,3}/",
- "include": ".page-show",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".listmain",
- "replaceElement": ".page-show",
- "lazyImgSrc": "lazysrc",
- "css": "[style='margin:3px 0 0 0;']{display:none!important}img[alt]{opacity: 1!important}"
-},
-{
- "name": "139人体艺术 - 圖片",
- "author": "skofkyo",
- "example": "https://www.139tu.com/rtysyz/20210829/8674.html",
- "url": "^https?://www\\.139tu\\.[a-z]{2,3}/[a-z]+/\\d+/\\d+(_\\d+)?\\.html",
- "action": 1,
- "init": "document.querySelectorAll('.img_box>a').forEach(a=>{a.outerHTML=a.innerHTML})",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".img_box img",
- "replaceElement": "#pages",
- "pageBar": 0
-},
-{
- "name": "139人体艺术",
- "author": "skofkyo",
- "example": "https://www.139tu.com/rtysyz/",
- "url": "^https?://www\\.139tu\\.[a-z]{2,3}/",
- "include": ".list_tags",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".list-box",
- "replaceElement": "#pages",
- "lazyImgSrc": "data-echo",
- "css": ".pagetual_pageBar{margin-top:4px!important}"
-},
-{
- "name": "Kemono - post",
- "author": "skofkyo",
- "example": "https://kemono.su/fantia/user/17148/post/1528173",
- "url": "^https?://kemono\\.su/fantia/user/\\d+/post/\\d+$",
- "nextLink": ".post__nav-item>a.next",
- "pageElement": ".post__header,.post__body"
-},
-{
- "name": "Kemono - user",
- "author": "skofkyo",
- "example": "https://kemono.su/fantia/user/17148?o=0",
- "url": "^https?://kemono\\.su/fantia/user/\\d+\\?o=",
- "nextLink": "a.pagination-button-after-current",
- "stopSign": [
- "",
- "li.pagination-button-disabled.pagination-button-current+li.pagination-button-disabled.pagination-button-after-current"
- ],
- "pageElement": ".card-list__items>article"
-},
-{
- "name": "Kemono - posts",
- "author": "skofkyo",
- "example": "https://kemono.su/posts",
- "url": "^https?://kemono\\.su/posts",
- "nextLink": "a.pagination-button-after-current",
- "stopSign": [
- "",
- ".card-list__item--no-results"
- ],
- "pageElement": ".card-list.card-list--legacy"
-},
{
"name": "套图之家 - 圖片",
"author": "skofkyo",
@@ -2291,28 +1833,6 @@
"pageElement": ".masonry-container",
"replaceElement": ".paging-navigation"
},
-{
- "name": "Pic Yailay - 圖片",
- "author": "skofkyo",
- "example": "https://pic.yailay.com/articles/U2d0UkZBREtjdUNFSHpwcGxiU1ZOUT09.html,https://nungvl.net/gallerys/87379.cg?page=1",
- "url": "^https?://(pic\\.yailay\\.com|nungvl\\.net)/(articles|gallerys)",
- "pinUrl": true,
- "nextLink": "//a[text()='Next >']",
- "pageElement": "img[onerror]+br,img[onerror]",
- "replaceElement": ".article-header>h1,.entry-title,.dept-ct.show-less,.pagination",
- "pageBar": 0,
- "css": ".spa-title,.spa-title+div{display:none!important}"
-},
-{
- "name": "Pic Yailay",
- "author": "skofkyo",
- "example": "https://pic.yailay.com/?page=1",
- "url": "^https?://(pic\\.yailay\\.com|nungvl\\.net)/",
- "nextLink": "a.page-numbers.next",
- "pageElement": ".videos",
- "replaceElement": ".pagination",
- "rate": 3
-},
{
"name": "imhentai.xxx - 圖片",
"author": "skofkyo",
@@ -2365,49 +1885,14 @@
"replaceElement": "#d_list_page,#d_list_foot"
},
{
- "name": "24tupian",
+ "name": "24tupian - 圖集列表",
"author": "skofkyo",
"example": "https://www.24tupian.org/",
"url": "^https?://www\\.24tupian\\.org/(meinv|nvyou|tuimo|gaoqing|model|class|Serch)",
"nextLink": "a.on+a[href$='html']",
"pageElement": ".lbleft>.lbl,.paihan.fl>ul,.model,.big.fl>ul,.gtps.fl>ul",
- "replaceElement": ".page"
-},
-{
- "name": "新老友图社 - 看圖",
- "author": "skofkyo",
- "example": "https://m.xtushe.com/photo/10377.html",
- "url": "^https?://m\\.xtushe\\.com/photo/\\w+\\.html",
- "nextLink": "li.next>a[title='下一张']",
- "pageElement": "#content-photo>img",
- "replaceElement": "#content-title,.pagebreak",
- "pageBar": 0
-},
-{
- "name": "新老友图社",
- "author": "skofkyo",
- "example": "https://m.xtushe.com/catalog/xinggan.html",
- "url": "^https?://m\\.xtushe\\.com/",
- "nextLink": "li.next>a[title='下一页']",
- "pageElement": "#content-list",
- "replaceElement": ".pagebreak"
-},
-{
- "name": "美女目录网 - 圖片列表模式載入原圖",
- "author": "skofkyo",
- "example": "https://www.girldir.com/photos/aozhongmaqin_list/",
- "url": "^https?://[^/]+/photos/",
- "include": [
- "//nav[@id='topNavBar']/a[@class='navbar-brand']/img[@src='/assets/logo.png']",
- ".page-item.active",
- "nav.pagination"
- ],
- "action": 1,
- "init": "document.querySelectorAll('source').forEach(e=>{e.remove()});document.querySelectorAll('picture>img').forEach(img=>{img.src=img.src.replace('.medium.','.big.')})",
- "nextLink": "li.page-item.active+li>a",
- "pageElement": ".list-page-box",
- "replaceElement": "nav.pagination",
- "pageInit": "doc.querySelectorAll('source').forEach(e=>{e.remove()});doc.querySelectorAll('picture>img').forEach(img=>{img.src=img.src.replace('.medium.','.big.')})"
+ "replaceElement": ".page",
+ "pageInit": "[...doc.querySelectorAll(\"img[src*='load.']\")].forEach(img => (img.src = 'https://imgs.diercun.com' + img.getAttribute('data')))"
},
{
"name": "美女目录网 - 圖片",
@@ -2464,44 +1949,6 @@
"pageBar": 0,
"css": ".pgg1+.hh{display:none!important}"
},
-{
- "name": "娱乐吧 - 圖片",
- "author": "skofkyo",
- "example": "www.yuleba.org,m.entba.net",
- "url": "^https?://(www\\.yuleba\\.org|m\\.entba\\.net)/a/",
- "nextLink": "//div[@class='paging']/a[text()='下一页']",
- "pageElement": ".main>p",
- "replaceElement": ".paging",
- "pageBar": 0
-},
-{
- "name": "娱乐吧",
- "author": "skofkyo",
- "example": "www.yuleba.org,m.entba.net",
- "url": "^https?://(www\\.yuleba\\.org|m\\.entba\\.net)/b/",
- "nextLink": "//div[@class='paging']/a[text()='下一页']",
- "pageElement": ".b_txt,.b_img:not(:nth-child(7))>ul",
- "replaceElement": ".paging"
-},
-{
- "name": "新闻吧 - xinwenba.net",
- "author": "skofkyo",
- "example": "www.xinwenba.net,m.xwbar.com",
- "url": "^https?://(www\\.xinwenba\\.net|m\\.xwbar\\.com)/plus/view",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".main>p",
- "replaceElement": ".paging",
- "pageBar": 0
-},
-{
- "name": "新闻吧 - xinwenba.net",
- "author": "skofkyo",
- "example": "www.xinwenba.net,m.xwbar.com",
- "url": "^https?://(www\\.xinwenba\\.net|m\\.xwbar\\.com)/plus/list",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".list_image>ul>li,.list_img",
- "replaceElement": ".paging"
-},
{
"name": "美图录 - 看圖",
"author": "skofkyo",
@@ -2686,10 +2133,9 @@
"example": "https://www.nlegs.com/girls/2022/10/01/28219.html",
"url": "^https?://www\\.nlegs\\.com/girls/[^.]+\\.html",
"nextLink": "li.active+li>a",
- "pageElement": "//div[a/div[contains(@style,'thumb') and span]]",
- "replaceElement": "#dnav",
- "pageBar": 0,
- "css": ".col-md-12.col-xs-12>img{width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}"
+ "pageElement": "//div[a/div[contains(@style,'thumb')]]",
+ "replaceElement": ".pagination",
+ "pageBar": 0
},
{
"name": "Nlegs",
@@ -2698,8 +2144,7 @@
"url": "^https?://www\\.nlegs\\.com/",
"nextLink": "li.active+li>a",
"pageElement": "//div[div/a/div/@class='img-div']",
- "replaceElement": ".pagination",
- "css": ".pagetual_pageBar{margin-top:10px!important}.pagetual_pageBar+div{margin-top:0px!important}"
+ "replaceElement": ".pagination"
},
{
"name": "Mitaku - 看圖禁用",
@@ -2942,41 +2387,6 @@
"pageElement": "#masonry",
"replaceElement": ".wp-pagenavi"
},
-{
- "name": "MM 范 - 圖片",
- "author": "skofkyo",
- "example": "https://www.95mm.vip/65309.html",
- "url": "^https?://www\\.95mm\\.\\w+/\\w+\\.html",
- "init": "let a=document.querySelector('.post a');a.outerHTML=a.innerHTML;",
- "include": ".post img[alt]",
- "nextLinkByUrl": [
- "/(\\d+)(/)?(\\d+)?(\\.html)",
- "/$1/{($3.0||1)+1}$4"
- ],
- "stopSign": [
- [
- ".post-title",
- "(\\d+)"
- ],
- [
- ".post-title",
- "\\/(\\d+)"
- ]
- ],
- "pageElement": ".post img",
- "replaceElement": "h1.h3",
- "pageAction": "document.querySelectorAll('.post img[title]').forEach(img=>{img.removeAttribute('title')})",
- "pageBar": 0,
- "css": "span.d-md-inline-block.d-none:not(.mx-1),.text-xs.text-muted>b{display:none!important}"
-},
-{
- "name": "MM 范",
- "author": "skofkyo",
- "example": "https://www.95mm.vip/qingchun",
- "url": "^https?://www\\.95mm\\.\\w+/(qingchun|sifang|xinggan|tag)?",
- "include": ".dposts-ajax-load",
- "loadMore": ".dposts-ajax-load"
-},
{
"name": "Xiuren 秀人网",
"author": "skofkyo",
@@ -3011,25 +2421,6 @@
"replaceElement": "#pageNum",
"css": "#infinite_scroll+.pagetual_pageBar{margin-top:-15px!important}.pagetual_pageBar+#infinite_scroll{margin-top:-15px!important}ul+.pagetual_pageBar{margin-top:-10px!important}"
},
-{
- "name": "Hentai Image - 圖片",
- "author": "skofkyo",
- "example": "hentai-img.com,hentai-cosplays.com,porn-images-xxx.com",
- "url": "^https?://(.+)?(porn-images-xxx|hentai-cosplays|hentai-img)\\.com/image/",
- "pageElement": ".icon-overlay",
- "pageBar": 0
-},
-{
- "name": "Hentai Image - 分類",
- "author": "skofkyo",
- "example": "https://ja.porn-images-xxx.com/search/",
- "url": "^https?://(.+)?(porn-images-xxx|hentai-cosplays|hentai-img)\\.com/(search|recently|ranking|search-video|ranking-video)/",
- "nextLink": "span+a",
- "pageElement": "#center>#display_area_image",
- "replaceElement": ".wp-pagenavi",
- "css": ".pagetual_pageBar{margin-top:-30px!important;}#post_list_title+#display_area_image,.pagetual_pageBar+#display_area_image{margin-bottom:0px!important;}",
- "rate": 3
-},
{
"name": "24fa",
"author": "skofkyo",
@@ -3059,8 +2450,7 @@
"url": "^https?://www\\.yasetube\\.com/",
"action": 1,
"waitElement": [
- ".video-preview+img[data-src].loaded",
- ".video-preview+img[data-src]:not(.loaded)"
+ ".video-preview+img[data-src].loaded"
],
"nextLink": "//li[a/@class='current']/following-sibling::li[1]/a",
"pageElement": "#main .videos-list",
@@ -3091,8 +2481,8 @@
{
"name": "fc2hub",
"author": "skofkyo",
- "example": "https://fc2hub.com/",
- "url": "^https?://fc2hub\\.com/",
+ "example": "https://javten.com/",
+ "url": "^https?://javten\\.com/",
"action": 1,
"nextLink": "a[rel='next']",
"pageElement": "//div[(div/div/@class='card shadow') and @class='row']",
@@ -3113,7 +2503,7 @@
"name": "PPP.Porn - 首頁(載入更多 …)",
"author": "skofkyo",
"example": "https://ppp.porn/",
- "url": "^https?://ppp\\.porn/$",
+ "url": "^https?://ppp\\.porn/",
"loadMore": ".btn.btn--sm"
},
{
@@ -3127,15 +2517,6 @@
"replaceElement": ".pagination",
"css": ".pagetual_pageBar{margin-top:-5px!important}"
},
-{
- "name": "magnetdl.com",
- "author": "skofkyo",
- "example": "www.magnetdl.com",
- "url": "^https?://www\\.magnetdl\\.com/",
- "nextLink": "id('pages')/a[contains(string(),'>')]",
- "pageElement": ".download>tbody>tr:nth-last-child(n+4)",
- "replaceElement": "#pages"
-},
{
"name": "tokyomotion",
"author": "skofkyo",
@@ -3229,7 +2610,7 @@
"url": "^https?://(jable\\.tv|fs1\\.app)/",
"action": 0,
"refreshByClick": "[data-action='ajax']",
- "nextLinkByJs": "let checked=doc.querySelector('.container li.active>a,.container li:has(>.active)+li>a');let blockId=checked.dataset.blockId;let parameters=checked.dataset.parameters;let[sortBy,from]=parameters.split(';');sortBy=sortBy.replace('sort_by:','');from=from.replace('from:','');let searchParams=new URLSearchParams({mode:'async',function:'get_block',block_id:blockId,sort_by:sortBy,from:from});return'?'+searchParams;",
+ "nextLinkByJs": "let checked=doc.querySelector('.container li.active>a,.container li:has(>.active)+li>a');let blockId=checked.dataset.blockId;let parameters=checked.dataset.parameters.replace(/.*;sort_by:/, '');let[sortBy,from]=parameters.split(';');sortBy=sortBy.replace('sort_by:','');from=from.replace('from:','');let searchParams=new URLSearchParams({mode:'async',function:'get_block',block_id:blockId,sort_by:sortBy,from:from});return'?'+searchParams;",
"pageElement": "section>.row",
"replaceElement": ".pagination",
"pageAction": "let ps=[...document.querySelectorAll('section>.row')];let last=ps.at(-1);last.querySelectorAll('.img-box>a').forEach(a=>{a.onmouseenter=e=>{let v=document.createElement('video');let img=a.querySelector('img');let src=img.dataset.preview;$(v).attr({loop:'',autoplay:'',src:src});$(v).css({position:'absolute',left:'0',top:'0',width:img.offsetWidth+'px',height:img.offsetHeight+'px',background:'#000000',visibility:'visible'});a.appendChild(v)};a.onmouseleave=e=>{a.querySelector('video').remove()}})",
@@ -3311,6 +2692,7 @@
"name": "绅士漫画 - 閱讀",
"author": "skofkyo",
"example": "https://wnacg.com/photos-view-id-15403544.html",
+ "action": 1,
"url": "^https?://(www\\.)?(wnacg|htcomic|ssmh\\d+)\\.[^/]+/photos-view",
"include": "span.newpagelabel",
"init": "let a=document.querySelector('#imgarea>a');a.outerHTML=a.innerHTML;",
@@ -3360,7 +2742,7 @@
"url": "^https?://www\\.lolhentai\\.net/",
"action": 1,
"waitElement": [
- "img.thumbnail"
+ "#thumbnails img.thumbnail"
],
"nextLink": "a[rel='next']",
"pageElement": "//div[ul/li/div/a/img[@class='thumbnail']]",
@@ -3376,6 +2758,20 @@
"papageElementeE": ".thumb, #doujin>a",
"replaceElement": ".navigation, #miniThumbContainer"
},
+{
+ "name": "nhentai - Free Hentai Manga, Doujinshi and Adult Comics",
+ "url": "^https?://nhentai\\.website/g/",
+ "example": "https://nhentai.website/g/514378/70/",
+ "preload": 0,
+ "action": 3
+},
+{
+ "name": "nhentai.net - Free Hentai Manga, Doujinshi and Adult Comics",
+ "url": "^https?://nhentai\\.net/g/\\d+/",
+ "example": "https://nhentai.net/g/583072/1",
+ "pageElement": "#image-container",
+ "nextLink": "#content > section.reader-bar > div.reader-pagination > a.next"
+},
{
"name": "Danbooru",
"author": "skofkyo",
@@ -3402,7 +2798,8 @@
"url": "^https?://(illusioncards\\.)?(gelbooru|tbib|safebooru|booru|rule34|hypnohub|xbooru)\\.(com|org|xxx|net)/.+s=list",
"nextLink": "a[alt='next']",
"pageElement": ".thumbnail-container, span.thumb",
- "replaceElement": "#paginator"
+ "replaceElement": "#paginator",
+ "action": 1
},
{
"name": "yande",
@@ -3447,10 +2844,10 @@
"example": "http://e-hentai.org/,https://exhentai.org/",
"url": "^https?://(e-hentai|exhentai)\\.org/",
"nextLink": "//table[@class='ptt']//a[string()='>'] | id('next') | id('unext')",
- "pageElement": ".itg>div,.itg>tbody>tr:not(:first-of-type),.gl1t, #gdt>div:not(.c), #img",
+ "pageElement": ".itg>div,.itg>tbody>tr:not(:first-of-type),.gl1t, #gdt>div:not(.c),#gdt>a:not(.c), #img",
"replaceElement": ".ptt,.ptb,.sn,.searchnav",
"css": "#img {max-width: 100% !important;height: auto !important;min-height: 400px;}",
- "pageInit": "doc.getElementById('img').setAttribute('onerror','setTimeout(()=>{this.src=this.src},2000)');"
+ "pageInit": "let img=doc.getElementById('img');img&&img.setAttribute('onerror','setTimeout(()=>{this.src=this.src.replace(/(\\\\?time=.*)?$/,`?time=${Date.now()}`)},3000)');"
},
{
"name": "177 漫画/xxiav - 圖片",
@@ -3509,30 +2906,6 @@
"lazyImgSrc": "data-srcset",
"css": ".home-rows-videos-div{margin-bottom:10px!important;}.search-pagination{margin-top:-50px!important;}"
},
-{
- "name": "Models Vibe",
- "author": "skofkyo",
- "example": "https://www.modelsvibe.com/albums/china/",
- "url": "^https?://www\\.modelsvibe\\.com/albums/[\\w-]+/",
- "nextLinkByUrl": [
- "(albums/[\\w-]+/)(page/(\\d+)/)?",
- "$1page/{$3+1}/"
- ],
- "pageElement": ".td_flex_block:not(.td-flex-radius),.td_block_inner.tdb-block-inner",
- "pageInit": "doc.querySelectorAll('span[data-img-url]').forEach(span=>{span.classList.add('td-animation-stack-type0-2');span.style.backgroundImage=`url('${span.dataset.imgUrl}')`})"
-},
-{
- "name": "Models Vibe 首頁",
- "author": "skofkyo",
- "example": "https://www.modelsvibe.com/",
- "url": "^https?://www\\.modelsvibe\\.com/$",
- "nextLinkByUrl": [
- "(^https?://www\\.modelsvibe\\.com/)(page/(\\d+)/)?",
- "$1page/{$3+1}/"
- ],
- "pageElement": ".td_flex_block:not(.td-flex-radius),.td_block_inner.tdb-block-inner",
- "pageInit": "doc.querySelectorAll('span[data-img-url]').forEach(span=>{span.classList.add('td-animation-stack-type0-2');span.style.backgroundImage=`url('${span.dataset.imgUrl}')`})"
-},
{
"name": "尤美图库",
"author": "skofkyo",
@@ -3688,7 +3061,7 @@
"name": "美人图 - 分類",
"author": "skofkyo",
"example": "https://meirentu.cc/group/xiuren.html",
- "url": "^https?://meirentu\\.\\w+/",
+ "url": "^https?://meirentu\\.\\w+/group",
"nextLink": "//a[text()='下页'] | //a[@class='current']/following-sibling::a[1]",
"stopSign": [
"ul.update_area_lists img"
@@ -3747,16 +3120,6 @@
"pageElement": ".g-main-grid>article",
"replaceElement": ".pagination"
},
-{
- "name": "Sex Nori",
- "author": "skofkyo",
- "example": "https://www.sexnori26.me/bbs/board.php?bo_table=av_korea",
- "url": "^https?://www\\.sexnori(\\d+)?\\.me/",
- "nextLink": "a.next",
- "pageElement": ".gallery-item",
- "replaceElement": ".eb-pagination",
- "css": ".pagetual_pageBar{margin-top:12px!important}.gallery-item {position: static !important;float: left !important;}"
-},
{
"name": "JavTorrent",
"author": "skofkyo",
@@ -3806,16 +3169,6 @@
"pageElement": ".listA:not(.clickadulist)",
"replaceElement": ".pages_c"
},
-{
- "name": "JavDove 番号鸽",
- "author": "skofkyo",
- "example": "https://www.javdove.com/videos/uncensored",
- "url": "^https?://www\\.javdove\\.com/",
- "nextLink": ".prevnext[rel='next']",
- "pageElement": ".row>.col-video",
- "replaceElement": ".pagination",
- "css": ".pagetual_pageBar{margin-top:-5px!important}"
-},
{
"name": "JAVMOST 禁用",
"author": "skofkyo",
@@ -3834,21 +3187,6 @@
"replaceElement": ".pagination",
"css": ".pagetual_pageBar{margin-top:-25px!important}"
},
-{
- "name": "Jav223",
- "author": "skofkyo",
- "example": "https://www.jav223.com/?m=video_list*5*1",
- "url": "^https?://www\\.jav223\\.com/",
- "action": 1,
- "nextLinkByJs": "let next = doc.querySelector('span.curwrpage+a'); if (next) return location.href.replace(/\\d+$/,'') + next.innerText",
- "pageElement": ".video-content",
- "waitElement": [
- "span.curwrpage"
- ],
- "replaceElement": "#wr-page",
- "pageAction": "let ge=e=>document.querySelector(e);let url=location.search.replace(/\\d+$/,'');setTimeout(()=>{let as=document.querySelectorAll('a.wrpage_number');as.forEach(a=>{a.href=url+a.innerText});let hp=ge('a.wr_pagefirst');if(hp){hp.href=url+'1'}let ep=ge('a.wr_pageend');if(ep){let epn=ge('span.wr_pagefirst').innerText.match(/(\\d+)/)[1];ep.href=url+epn}let pp=ge('a.wr_pagepre');if(pp){let cp=ge('span.curwrpage').innerText;let cpn=cp-1;pp.href=url+cpn}let np=ge('a.wr_pagenext');if(np){let npn=ge('span.curwrpage+a').innerText;np.href=url+npn}},1000)",
- "css": ".pagetual_pageBar{margin-top:-5px!important}"
-},
{
"name": "Avgle & AV01",
"author": "skofkyo",
@@ -3883,7 +3221,7 @@
"example": "https://porn78.info/,https://nyaa.porn78.info/",
"url": "^https?://(nyaa\\.)?porn78.info/",
"action": 1,
- "nextLink": ".next>a",
+ "nextLink": ".general-pagination .selected+li>a",
"pageElement": "#portfolio>li",
"replaceElement": ".general-pagination"
},
@@ -3935,16 +3273,6 @@
"pageElement": ".gridview-posts",
"replaceElement": ".nav-links"
},
-{
- "name": "Avbebe",
- "author": "skofkyo",
- "example": "https://avbebe.com/",
- "url": "^https?://avbebe\\.com/",
- "nextLink": ".next",
- "pageElement": ".jeg_block_container",
- "replaceElement": ".jeg_block_navigation",
- "css": ".pagetual_pageBar{margin-top:-16px!important}"
-},
{
"name": "Latino Hentai",
"author": "skofkyo",
@@ -3954,147 +3282,60 @@
"pageElement": ".items",
"replaceElement": ".pagination"
},
-{
- "name": "ACG RW",
- "author": "skofkyo",
- "example": "https://www.acgrw.net/category/lifan/",
- "url": "^https?://www\\.acgrw\\.net/",
- "nextLink": "a.next",
- "pageElement": ".uk-animation-slide-bottom-small",
- "replaceElement": ".nav-links",
- "pageInit": "doc.querySelectorAll('.media-content.scrollLoading:not(.ojbk)').forEach(div=>{div.style.backgroundImage=`url('${div.dataset.xurl}')`;div.classList.add('ojbk');div.removeAttribute('data-xurl')})"
-},
-{
- "name": "YouJizz",
- "author": "skofkyo",
- "example": "https://www.youjizz.com/",
- "url": "^https?://www\\.youjizz\\.com/",
- "action": 1,
- "nextLink": ".pagination-next",
- "pageElement": "//div[div[@class='video-thumb']]",
- "replaceElement": ".pagination, .mobilePager",
- "pageInit": "doc.querySelectorAll('video[preload]').forEach(e=>{e.src=e.parentNode.getAttribute('data-clip')})",
- "pageAction": "function gax(x){let nodes=[];let results=document.evaluate(x,document,null,XPathResult.ANY_TYPE,null);let node;while(node=results.iterateNext()){nodes.push(node)}return nodes}let ps=gax(\"//div[div[@class='video-thumb']]\");let last=ps.length-1;ps[last].querySelectorAll('a.frame.video').forEach(a=>{a.onmouseenter=e=>{let v=a.querySelector('video');v.style='';v.setAttribute('loop','')};a.onmouseleave=e=>{let v=a.querySelector('video');v.style.display='none';v.removeAttribute('loop')}})"
-},
-{
- "name": "PornPic",
- "author": "skofkyo",
- "example": "https://www.pornpic.com/",
- "url": "^https?://www\\.pornpic\\.com/",
- "action": 2,
- "pageElement": ".grid.gallery-grid"
-},
-{
- "name": "Good Sex Porn",
- "author": "skofkyo",
- "example": "http://goodsexporn.org/",
- "url": "^https?://goodsexporn\\.org/",
- "nextLink": ".pagination>span+a:not(.next)",
- "pageElement": ".block.block",
- "replaceElement": ".pagination"
-},
-{
- "name": "EPORNER",
- "author": "skofkyo",
- "example": "https://www.eporner.com/",
- "url": "^https?://[a-z]{2,3}\\.eporner\\.com/",
- "nextLink": ".nmnext",
- "pageElement": "#vidresults>[id],.photosgrid,main>.mbprofile",
- "replaceElement": ".numlist2",
- "pageAction": "EPtbnsStandardRebind()",
- "css": ".pagetual_pageBar{margin-top:-15px!important}.photosgrid+.pagetual_pageBar{margin-top:10px!important}.mbprofile+.pagetual_pageBar{margin-top:0px!important}.mbphoto2+.pagetual_pageBar{display:none!important}"
-},
-{
- "name": "xHamster gallery2",
- "author": "skofkyo",
- "example": "https://zh.xhamster.com/photos/gallery/15979608/513740284",
- "url": "^https?://([a-z]{2}\\.)?xhamster\\.com/photos/gallery/",
- "exclude": ".gallery-list",
- "nextLink": ".fotorama__arr--next",
- "stopSign": [
- [
- ".photo-amounts-info",
- "^(\\d+)"
- ],
- [
- ".photo-amounts-info",
- "(\\d+)$"
- ]
- ],
- "pageElement": ".fotorama__active>img",
- "replaceElement": ".gallery-thumbs,.photo-amounts-info",
- "pageBar": 0,
- "css": "#photo_slider *{overflow: initial !important;position: initial !important;}.fotorama__stage{height:auto!important;}.fotorama__loaded--img:not(.fotorama__active){display:none!important}.fotorama__img {max-width: 98% !important;display: block !important;margin: 0 auto !important;}"
-},
-{
- "name": "xHamster gallery1",
- "author": "skofkyo",
- "example": "https://zh.xhamster.com/photos/gallery/selfie-porn-pic-134-15984561,https://zh.xhamster.com/photos/gallery/selfie-porn-pic-122-15979608",
- "url": "^https?://([a-z]{2}\\.)?xhamster\\.com/photos/gallery/",
- "include": ".gallery-list",
- "pinUrl": true,
- "action": 1,
- "waitElement": [
- "",
- ".image-thumb:not([style])"
- ],
- "nextLink": ".next>a[href^='http']",
- "pageElement": ".gallery-list",
- "replaceElement": ".pager-section>[data-sync]",
- "css": ".gallery-list img{width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}"
+{
+ "name": "ACG - 🏠 西普拉斯驿站|小西驿站 - 数码,音乐,ACG论坛",
+ "url": "^https?://post\\.cplus8\\.com/",
+ "example": "https://post.cplus8.com/t/acg",
+ "pageElement": ".DiscussionList-discussions>li",
+ "nextLink": "//li[button[contains(@class, 'Button--primary') and @data-page]]/following-sibling::li[1]/button[@data-page]"
},
{
- "name": "xHamster photos",
- "author": "skofkyo",
- "example": "https://zh.xhamster.com/photos",
- "url": "^https?://([a-z]{2}\\.)?xhamster\\.com/photos",
- "pinUrl": true,
- "nextLink": "//li[a[@class='page-button-link page-button-link--active']]/following-sibling::li[1]/a",
- "pageElement": ".thumb-list.gallery.thumb-list--sidebar",
- "replaceElement": ".desktop-pagination",
- "pageInit": "doc.querySelectorAll('div.thumb-image-container__image[data-lazy]:not([style])').forEach(div=>{div.querySelector('.dots-loader').remove();div.style.backgroundImage=`url('${div.dataset.lazy}')`})"
+ "name": "韩漫天堂漫画",
+ "url": "^https?://\\w+\\.npdn\\.top/chapter/",
+ "example": "https://w226.npdn.top/chapter/yirenzhixia/101661.html",
+ "nextLink": "#mainControlNext",
+ "action": 2,
+ "pageElement": "body > div.main > ul"
},
{
- "name": "xHamster channels",
+ "name": "YouJizz",
"author": "skofkyo",
- "example": "https://zh.xhamster.com/channels",
- "url": "^https?://([a-z]{2}\\.)?xhamster\\.com/channels",
- "nextLink": "//li[a[@class='page-button-link page-button-link--active']]/following-sibling::li[1]/a",
- "pageElement": ".width-wrap>.best-list-block>.root-ddffe",
- "replaceElement": ".desktop-pagination",
- "rate": 3
+ "example": "https://www.youjizz.com/",
+ "url": "^https?://www\\.youjizz\\.com/",
+ "action": 1,
+ "nextLink": ".pagination-next",
+ "pageElement": "//div[div[@class='video-thumb']]",
+ "replaceElement": ".pagination, .mobilePager",
+ "pageInit": "doc.querySelectorAll('video[preload]').forEach(e=>{e.src=e.parentNode.getAttribute('data-clip')})",
+ "pageAction": "function gax(x){let nodes=[];let results=document.evaluate(x,document,null,XPathResult.ANY_TYPE,null);let node;while(node=results.iterateNext()){nodes.push(node)}return nodes}let ps=gax(\"//div[div[@class='video-thumb']]\");let last=ps.length-1;ps[last].querySelectorAll('a.frame.video').forEach(a=>{a.onmouseenter=e=>{let v=a.querySelector('video');v.style='';v.setAttribute('loop','')};a.onmouseleave=e=>{let v=a.querySelector('video');v.style.display='none';v.removeAttribute('loop')}})"
},
{
- "name": "xHamster creators",
+ "name": "PornPic",
"author": "skofkyo",
- "example": "https://zh.xhamster.com/creators",
- "url": "^https?://([a-z]{2}\\.)?xhamster\\.com/creators",
- "nextLink": "//li[a[@class='page-button-link page-button-link--active']]/following-sibling::li[1]/a",
- "pageElement": ".width-wrap>div[class^=list]",
- "replaceElement": ".desktop-pagination",
- "rate": 3
+ "example": "https://www.pornpic.com/",
+ "url": "^https?://www\\.pornpic\\.com/",
+ "action": 2,
+ "pageElement": ".grid.gallery-grid"
},
{
- "name": "xHamster pornstars",
+ "name": "Good Sex Porn",
"author": "skofkyo",
- "example": "https://zh.xhamster.com/pornstars",
- "url": "^https?://([a-z]{2}\\.)?xhamster\\.com/pornstars",
- "nextLink": "//li[a[@class='page-button-link page-button-link--active']]/following-sibling::li[1]/a",
- "pageElement": ".width-wrap>div[class^=list]",
- "replaceElement": ".desktop-pagination",
- "rate": 3
+ "example": "http://goodsexporn.org/",
+ "url": "^https?://goodsexporn\\.org/",
+ "nextLink": ".pagination>span+a:not(.next)",
+ "pageElement": ".block.block",
+ "replaceElement": ".pagination"
},
{
- "name": "xHamster",
+ "name": "EPORNER",
"author": "skofkyo",
- "example": "https://zh.xhamster.com/newest",
- "url": "^https?://([a-z]{2}\\.)?xhamster\\.com/",
- "exclude": ".fotorama__img",
- "nextLink": "a[rel='next']",
- "pageElement": ".thumb-list",
- "replaceElement": ".pager-section",
- "pageAction": "let gae=e=>document.querySelectorAll(e);let ps=gae('.thumb-list');let last=ps.length-1;ps[last].querySelectorAll('a[data-previewvideo]').forEach(a=>{a.onmouseenter=e=>{let v=document.createElement('video');v.setAttribute('loop','loop');v.setAttribute('autoplay','autoplay');v.setAttribute('playsinline','playsinline');v.setAttribute('webkitplaysinline','webkitplaysinline');v.setAttribute('src',a.getAttribute('data-previewvideo'));v.setAttribute('class','thumb-image-container__video');v.setAttribute('eid1','156');a.appendChild(v)};a.onmouseleave=e=>{a.querySelector('video').remove()}})",
- "css": ".thumb-list__item+div[class^=root][style*='height']{display:none!important;}"
+ "example": "https://www.eporner.com/",
+ "url": "^https?://[a-z]{2,3}\\.eporner\\.com/",
+ "nextLink": ".nmnext",
+ "pageElement": "#vidresults>[id],.photosgrid,main>.mbprofile",
+ "replaceElement": ".numlist2",
+ "pageAction": "EPtbnsStandardRebind()",
+ "css": ".pagetual_pageBar{margin-top:-15px!important}.photosgrid+.pagetual_pageBar{margin-top:10px!important}.mbprofile+.pagetual_pageBar{margin-top:0px!important}.mbphoto2+.pagetual_pageBar{display:none!important}"
},
{
"name": "色色啦",
@@ -4111,6 +3352,7 @@
"name": "91Porn",
"author": "skofkyo",
"example": "http://91porn.com/index.php",
+ "action": 1,
"url": "^https?://(0118\\.)?(91porn|workarea7)\\.(com|live)/",
"nextLink": "//a[text()='»']",
"pageElement": ".row .row>div",
@@ -4200,7 +3442,7 @@
"pinUrl": true,
"action": 1,
"nextLink": ".page_next:not(.disabled)>a",
- "pageElement": "#singleFeedSection>.pcVideoListItem,#videoCategory>.pcVideoListItem,#videoSearchResult>.pcVideoListItem,.videoList,.homeSection",
+ "pageElement": "#singleFeedSection>.pcVideoListItem,#videoCategory>.pcVideoListItem,#videoSearchResult>.pcVideoListItem,.videoList,.homeSection,#recommendedListings,#mostRecentVideosSection",
"replaceElement": ".paginationGated"
},
{
@@ -4208,29 +3450,12 @@
"author": "skofkyo",
"example": "https://www.xvideos.com/",
"url": "^https?://www\\.(xvideos|xnxx)\\.com/",
- "nextLink": "//li[a/@class='active']/following-sibling::li[1]/a",
+ "nextLink": "//li[a/@class='active']/following-sibling::li[1]/a | //a[@class='no-page next-page']",
"pinUrl": true,
"pageElement": ".mozaique.cust-nb-cols",
"replaceElement": ".pagination",
"pageAction": "xv.thumb_block_initiator.init_listing()"
},
-{
- "name": "麻豆村",
- "author": "skofkyo",
- "example": "https://madoucun.com/",
- "url": "^https?://madoucun\\.com/",
- "include": ".hl-page-wrap",
- "pageElement": ".hl-list-item",
- "replaceElement": ".hl-page-wrap",
- "pageInit": "doc.querySelectorAll('a[data-original]').forEach(a=>{a.style.backgroundImage=`url('${a.dataset.original}')`})"
-},
-{
- "name": "麻豆社,草麻豆",
- "author": "skofkyo",
- "example": "https://madou.club/",
- "url": "^https?://madou\\.club/",
- "loadMore": ".ias_trigger>a"
-},
{
"name": "CableAV",
"author": "skofkyo",
@@ -4240,30 +3465,6 @@
"pageElement": ".blog-items>article",
"replaceElement": ".wp-pagenavi"
},
-{
- "name": "肉漫屋 - 閱讀",
- "author": "skofkyo",
- "example": "https://rouman5.com/books/354b56da-1ab9-4909-9330-743842c5a5bf/0",
- "url": "^https?://rouman[0-9]{1,2}\\.[a-z]{3}/books/[^/]+/",
- "history": 2,
- "action": 2,
- "init": "document.querySelector(\"div[class^='id_chapterRoot']\").setAttribute('style','padding-right:0px!important;padding-left:0px!important;');",
- "nextLink": "//a[text()='下一頁']",
- "pageElement": "//div[div/img[@id]]",
- "replaceElement": "div[class^='id_pagination']",
- "pageBarText": 1,
- "css": "inIframe:nav.navbar,#__next>div[class^='footer'],.row,div[class^='id_pagination']{display:none!important}.container{padding-right:0px!important;padding-left:0px!important;max-width: 800px!important;}"
-},
-{
- "name": "肉漫屋",
- "author": "skofkyo",
- "example": "https://rouman5.com/books,https://rouman01.xyz/books",
- "url": "^https?://rouman\\d{1,2}\\.[a-z]{3}/",
- "include": "div[class^='pagination']",
- "nextLink": "//a[text()='下一頁']",
- "pageElement": "ul[class^='books_list']>li",
- "replaceElement": "div[class^='pagination']"
-},
{
"name": "肉視頻",
"author": "skofkyo",
@@ -4301,14 +3502,6 @@
"url": "^https?://onejav\\.com/$",
"loadMore": "#button-load-more"
},
-{
- "name": "女神社",
- "author": "skofkyo",
- "example": "https://nshens.com/,https://inewgirl.com/",
- "url": "^https?://(nshens\\.com|inewgirl\\.com)/",
- "include": ".v-pagination",
- "pageElement": ".justify-start>.col"
-},
{
"name": "微圖坊 - 看圖",
"author": "skofkyo",
@@ -4391,15 +3584,6 @@
"pageElement": "table.torrent-list>tbody>tr",
"replaceElement": "ul.pagination"
},
-{
- "name": "U9A9",
- "author": "skofkyo",
- "example": "https://u9a9.net/",
- "url": "^https?://u9a9\\.[a-z]{2,3}",
- "nextLink": "li.active+li>a",
- "pageElement": "table>tbody>tr",
- "replaceElement": "nav>.pagination"
-},
{
"name": "Mixfemdomcc",
"author": "skofkyo",
@@ -4417,8 +3601,7 @@
"url": "^https?://femdomup\\.net/",
"nextLink": "//a[text()='Next']",
"pageElement": "article.shortstory",
- "replaceElement": ".navigation",
- "pageAction": "let url=document.querySelector(\"script[src*='cat.js']\").src;if(url)fetch(url).then(res=>res.text()).then((res)=>{eval(res)})"
+ "replaceElement": ".navigation"
},
{
"name": "xstarshub",
@@ -4450,15 +3633,6 @@
"replaceElement": ".pagination",
"pageAction": "image_rotate('.video-rotate .thumb')"
},
-{
- "name": "MISSAV",
- "author": "skofkyo",
- "example": "https://missav.com/dm93/fc2",
- "url": "^https?://missav.com/",
- "nextLink": "a[rel='next']",
- "pageElement": "//div[div/div/a/video] | //div[div/a/img[@data-src] and contains(@class,'shadow-lg')]",
- "replaceElement": "nav.flex"
-},
{
"name": "愛污傳媒",
"author": "skofkyo",
@@ -4481,24 +3655,6 @@
"pageElement": ".videos-list>article",
"replaceElement": ".pagination"
},
-{
- "name": "fanxxx.net",
- "author": "skofkyo",
- "example": "https://fanxxx.net/",
- "url": "^https?://fanxxx\\.net/",
- "nextLink": "a[rel='next']",
- "pageElement": ".video-list",
- "replaceElement": ".pagenavi"
-},
-{
- "name": "JAVDAY",
- "author": "skofkyo",
- "example": "https://javday.tv/category/uncensored-leaked/",
- "url": "^https?://javday\\.tv/(category|search)/",
- "nextLink": ".layui-laypage-next",
- "pageElement": ".videoGroup .video-wrapper .col-style.loaded",
- "replaceElement": "div.av"
-},
{
"name": "AVPRO - 搜索",
"author": "skofkyo",
@@ -4522,20 +3678,11 @@
"pageElement": ".videos-latest-list>*",
"replaceElement": ".pagination"
},
-{
- "name": "AV時間",
- "author": "skofkyo",
- "example": "https://avtime.tv/category/28/",
- "url": "^https?://avtime\\.tv/",
- "nextLink": "//a[span[text()='下一页']]",
- "pageElement": "//ul[@class='wntheme-page text-center clearfix']/preceding-sibling::div[1]",
- "replaceElement": ".wntheme-page",
- "pageAction": "document.querySelectorAll('div[data-original]').forEach(div=>{div.style.backgroundImage=`url('${div.dataset.original}')`})"
-},
{
"name": "Supjav",
"author": "skofkyo",
"example": "https://supjav.com/ja/category/uncensored-jav",
+ "action": 1,
"url": "^https?://supjav\\.com/(zh/|ja/)?(\\?s=|popular|category)",
"nextLink": "li.active+li>a",
"pageElement": ".posts.clearfix>*",
@@ -4551,58 +3698,6 @@
"pageElement": "#content>.post.f",
"replaceElement": ".page-navigator"
},
-{
- "name": "NETFLAV3",
- "author": "skofkyo",
- "example": "https://netflav5.com/all?genre=%E6%80%A7%E6%84%9F%E7%9A%84&page=2",
- "url": "^https?://(www\\.)?netflav5\\.com/all\\?genre=.+(&page=\\d+)?$|^https?://(www\\.)?netflav5\\.com/actress",
- "pinUrl": true,
- "init": "let gae=e=>document.querySelectorAll(e);let ds=document.querySelectorAll(\"div[class^='genre_filter_item']\");ds.forEach(div=>{div.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});let as=document.querySelectorAll('.desktop_header_root>div>a.desktop_header_item:not([href=\"/\"])');as.forEach(a=>{a.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});",
- "action": 1,
- "nextLinkByJs": "let next=doc.querySelector('a.active.item+a.item:not(.icon)');if(next)return location.origin+location.pathname+location.search.replace(/&page=\\d+/,'')+'&page='+next.getAttribute('value')",
- "pageElement": "//div[@class='general_pagination']/preceding-sibling::div[1]",
- "waitElement": [
- ".general_pagination a.active",
- "div.lazyload-placeholder,.grid_cover.image:not(.fadeIn),.lazyload-wrapper img[src^='data']"
- ],
- "replaceElement": ".general_pagination",
- "rate": 3,
- "pageAction": "setTimeout(()=>{let as=document.querySelectorAll('#general-pagination a');as.forEach(a=>{let link=location.search.replace(/&page=\\d+/,'')+'&page='+a.getAttribute('value');a.href=link})},200)"
-},
-{
- "name": "NETFLAV2",
- "author": "skofkyo",
- "example": "https://netflav5.com/uncensored?genre=FC2PPV",
- "url": "^https?://(www\\.)?netflav5\\.com/(censored|uncensored|chinese-sub|actress)\\?genre=[^&]+(&page=\\d+)?$",
- "init": "let gae=e=>document.querySelectorAll(e);let ds=gae(\"div[class^='genre_filter_item']\");ds.forEach(div=>{div.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});let as=gae('.desktop_header_root>div>a.desktop_header_item:not([href=\"/\"])');as.forEach(a=>{a.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});",
- "action": 1,
- "nextLinkByJs": "let next=doc.querySelector('a.active.item+a.item:not(.icon)');if(next)return location.origin+location.pathname+location.search.replace(/&page=\\d+/,'')+'&page='+next.getAttribute('value')",
- "pageElement": "//div[@class='general_pagination']/preceding-sibling::div[1]",
- "waitElement": [
- "#general-pagination a.active",
- "div.lazyload-placeholder,.grid_cover.image:not(.fadeIn),.lazyload-wrapper img[src^='data']"
- ],
- "replaceElement": "#general-pagination",
- "rate": 3,
- "pageAction": "setTimeout(()=>{let as=document.querySelectorAll('#general-pagination a');as.forEach(a=>{let link=location.search.replace(/&page=\\d+/,'')+'&page='+a.getAttribute('value');a.href=link})},200)"
-},
-{
- "name": "NETFLAV1",
- "author": "skofkyo",
- "example": "https://netflav5.com/uncensored",
- "url": "^https?://(www\\.)?netflav5\\.com/(censored|uncensored|chinese-sub|actress)(\\?page=\\d+)?$",
- "init": "let gae=e=>document.querySelectorAll(e);let ds=gae(\"div[class^='genre_filter_item']\");ds.forEach(div=>{div.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});let as=gae('.desktop_header_root>div>a.desktop_header_item:not([href=\"/\"])');as.forEach(a=>{a.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});",
- "action": 1,
- "nextLinkByJs": "let next=doc.querySelector('a.active.item+a.item:not(.icon)');if(next)return location.origin+location.pathname+'?page='+next.getAttribute('value')",
- "pageElement": "//div[@class='general_pagination']/preceding-sibling::div[1]",
- "waitElement": [
- "#general-pagination a.active",
- "div.lazyload-placeholder,.grid_cover.image:not(.fadeIn),.lazyload-wrapper img[src^='data']"
- ],
- "replaceElement": "#general-pagination",
- "rate": 3,
- "pageAction": "setTimeout(()=>{let as=document.querySelectorAll('#general-pagination a');as.forEach(a=>{let link=location.pathname+'?page='+a.getAttribute('value');a.href=link})},200)"
-},
{
"name": "avple.tv - 類別",
"author": "skofkyo",
@@ -4666,34 +3761,12 @@
"author": "skofkyo",
"example": "https://hotgirl.asia/imiss%e7%88%b1%e8%9c%9c%e7%a4%be-vol-693-lavinia%e8%82%89%e8%82%89/",
"url": "^https?://hotgirl\\.asia/[^/]+/",
- "include": ".mx-auto",
- "init": "document.querySelectorAll(\"img[alt][src^='data']\").forEach(e=>{e.parentNode.remove()})",
"nextLink": "li.active+li>a",
"pageElement": "//div[@class='galeria_img'][img[starts-with(@src,'http')]]",
+ "replaceElement": "#pagination",
"css": "#footer,#commentfb,.content-kuss{display: none!important;}",
"pageBar": 0
},
-{
- "name": "Taotuxp.com - 看圖",
- "author": "skofkyo",
- "example": "https://www.taotucc.com/252555.html",
- "url": "^https?://www\\.taotucc\\.com/\\d+\\.html",
- "nextLink": ".pagelist>span+a",
- "pageElement": "#post_content>p",
- "replaceElement": ".pagelist",
- "pageBar": 0,
- "css": "#post_content img{width:auto!important;height:auto!important;max-width:100%!important;display:block!important;margin:0 auto !important}#content p{margin:0!important}"
-},
-{
- "name": "Taotuxp.com - 分類",
- "author": "skofkyo",
- "example": "https://www.taotucc.com/",
- "url": "^https?://www\\.taotucc\\.com/",
- "nextLink": "a.current+a",
- "pageElement": "#post_container",
- "replaceElement": ".pagination",
- "css": ".pagetual_pageBar{margin-top:-8px!important}"
-},
{
"name": "Xgirls - 看圖",
"author": "skofkyo",
@@ -4713,18 +3786,6 @@
"pageElement": "//div[@class='container']/div[@class='row']/div/div[div/div[@class='card-wrapper']/div[@class='card-img']/a/img][@class='row']/*",
"replaceElement": ".pagination"
},
-{
- "name": "优丝库HD - 分類",
- "author": "skofkyo",
- "example": "https://yskhd.com/archives/category/xiuren/xiuren%e7%a7%80%e4%ba%ba%e7%bd%91?t",
- "url": "^https?://yskhd\\.(com|me)/",
- "include": ".pagination",
- "init": "document.querySelectorAll('img[data-src]').forEach(img=>{img.src=img.getAttribute('data-src')})",
- "nextLink": "li.active+li>a",
- "pageElement": ".posts",
- "replaceElement": ".pagination",
- "css": ".pagetual_pageBar{margin-top:-8px!important}.grids{margin:0 -10px 0px!important}"
-},
{
"name": "心动美图 - 看圖",
"author": "skofkyo",
@@ -4784,7 +3845,7 @@
"pageInit": "doc.querySelectorAll('img[data-src]').forEach(e=>{e.src=e.dataset.src;e.removeAttribute('data-src')})",
"replaceElement": ".prevNext",
"pageBarText": "return doc.querySelector('.tag[checked=true]').innerText;",
- "css": ".banner_ad{display:none!important}.pagetual_pageBar{margin-top:2px!important}"
+ "css": "body{overflow:unset!important}.banner_ad,.swal2-container,.article:has(.media),.jquery-modal.blocker.current,.push-top-container{display:none!important}"
},
{
"name": "丽图·污漫画 - 分類",
@@ -4794,7 +3855,7 @@
"nextLink": "a.next",
"pageElement": ".list>.item",
"replaceElement": ".pager",
- "css": "._728x90{display:none!important}"
+ "css": "body{overflow:unset!important}.banner_ad,.swal2-container,.article:has(.media),.jquery-modal.blocker.current,.push-top-container{display:none!important}"
},
{
"name": "海棠小说网 - 手机阅读",
@@ -4843,7 +3904,7 @@
"div.article:not(.result)+div.pager",
"div.article.result+div.pager"
],
- "css": ".pagetual_pageBar+div{margin-top:-5px !important;}.slider-ad,.jquery-modal.blocker.current,.article.ad,.body>*:not(.article):not(.pager),.banner_ad{display:none!important}",
+ "css": ".slider-ad,.jquery-modal.blocker.current,.article.ad,.body>*:not(.article):not(.pager),.banner_ad{display:none!important}",
"rate": 3
},
{
@@ -4870,7 +3931,7 @@
"div.article>div.pager:first-child",
"div.article>div.pager:last-child"
],
- "css": ".photos>div.item,.jquery-modal.blocker.current,.slider-ad,.article.ad,.pager>.tips,body>footer~*:not([id^='pv-']):not([class^='pv-']):not(.pagetual_tipsWords):not(.customPicDownloadMsg):not(#customPicDownload):not(a),.photoMask,.banner_ad{display: none!important;}",
+ "css": "body{overflow:unset!important}.push-slider,.article:has(>div>.media),div:has(>.links),a[clickmode=ad],a:has(>div>div>img),.photos>div.item,.jquery-modal.blocker.current,.push-top,.push-bottom,.slider-ad,.article.ad,.pager>.tips,.photoMask,.banner_ad,.banner-sexgps,div[class*='backdrop-show']{display: none!important;}",
"pageBar": 0
},
{
@@ -4887,17 +3948,7 @@
"div.article>div.pager:last-child"
],
"rate": 3,
- "css": ".pagetual_pageBar{margin-bottom:5px!important}.videos .pagetual_pageBar{margin-top:30px!important;margin-bottom:0px!important}.slider-ad,.article.ad,.jquery-modal.blocker.current,.banner_ad,.tips,.aside>.center,.item._300x250{display:none!important}"
-},
-{
- "name": "YINGPIAN影片社",
- "author": "skofkyo",
- "example": "https://zhipai12.com/",
- "url": "^https?://zhipai12\\.com/",
- "nextLink": "a[rel='next'],.nav-previous>a",
- "pageElement": "div[id^='post-']",
- "replaceElement": ".wp-pagenavi",
- "rate": 3
+ "css": ".videos .pagetual_pageBar{margin-top:30px!important;margin-bottom:0px!important}.slider-ad,.article.ad,.jquery-modal.blocker.current,.banner_ad,.tips,.aside>.center,.item._300x250{display:none!important}"
},
{
"name": "國模網",
@@ -4909,59 +3960,6 @@
"pageElement": "#main > article",
"replaceElement": "#nav-below"
},
-{
- "name": "MIC MIC IDOL",
- "author": "skofkyo",
- "example": "https://www.micmicidol.club/",
- "url": "^https?://www\\.micmicidol\\.club/",
- "action": 1
-},
-{
- "name": "自拍图库",
- "author": "skofkyo",
- "example": "https://xn--yzp-zipaipiccom-6m3z988bh2ek30lissa.zipaitk.com/",
- "url": "^https?://.*(zipaipic|zipaitk)\\.com/",
- "action": 1,
- "nextLink": "//a[text()='下一页']",
- "pageElement": "#tiles",
- "replaceElement": ".page"
-},
-{
- "name": "性趣套圖 - 搜索",
- "author": "skofkyo",
- "example": "https://534798.xyz/e/search/result/?searchid=7898",
- "url": "^https?://534798\\.xyz/e/search/",
- "nextLink": "//a[text()='下一页']",
- "pageElement": "h2.r,table[width^='8']",
- "replaceElement": ".list_page",
- "css": "table.nav,table[width^='8'] tr:nth-child(1){display:none!important;}td{font:12px/1.5 Verdana,Arial,Helvetica,sans-serif,'微软雅黑'!important}"
-},
-{
- "name": "性趣套圖 / H漫画 - 看圖",
- "author": "skofkyo",
- "example": "https://534798.xyz/e/action/ShowInfo.php?classid=1&id=23726,https://123548.xyz/e/action/ShowInfo.php?classid=1&id=28294",
- "url": "^https?://(123548|534798)\\.xyz/e/action/ShowInfo\\.php",
- "pinUrl": true,
- "init": "let ge=e=>document.querySelector(e);let e=ge('.entry');e.innerHTML=e.innerHTML.replace('\">','');document.addEventListener('keydown',(e)=>{let key=window.event?e.keyCode:e.which;if(key=='39'){let n=ge('.nextinfo a');if(n)n.click()}});document.addEventListener('keydown',(e)=>{let key=window.event?e.keyCode:e.which;if(key=='37'){let p=ge('.nextinfo p:last-child a');if(p)p.click()}});",
- "nextLink": ".pageLink b+a",
- "pageElement": ".entry img",
- "replaceElement": ".pageLink",
- "pageBar": 0,
- "rate": 10,
- "css": "aside.side,.pageLink{display:none!important;}.main-content{margin-left:0px!important;}"
-},
-{
- "name": "性趣套圖 / H漫画 - 列表",
- "author": "skofkyo",
- "example": "https://534798.xyz/e/action/ListInfo/?classid=1",
- "url": "^https?://(123548|534798)\\.xyz/e/action/ListInfo",
- "nextLink": "//a[text()='下一页']",
- "pageElement": ".bloglist > ul",
- "replaceElement": ".pageLink",
- "css": ".pagetual_pageBar{width:98.6%!important;}aside.side{display:none!important;}.main-content{margin-left:0px!important;}body{background:#EDEDED!important;}",
- "initRun": 1,
- "autoLoadNum": 1
-},
{
"name": "雅拉伊",
"author": "skofkyo",
@@ -4987,12 +3985,12 @@
"name": "Mox.moe",
"author": "skofkyo",
"example": "https://mox.moe/",
- "url": "^https?://mox\\.moe",
+ "url": "^https?://(mox|kox|kxo|koz)\\.moe",
"action": 1,
"wait": 1000,
- "nextLink": "//a[button/text()='下頁']",
- "pageElement": ".listbg",
- "replaceElement": "td.listtitle[colspan='5']",
+ "nextLink": "//button[@name='link_page']/b/../../following-sibling::a[1]",
+ "pageElement": "tr.listbg",
+ "replaceElement": "tr[style='vertical-align:top']:first-child",
"rate": 3
},
{
@@ -5041,32 +4039,6 @@
".o-list--footer"
]
},
-{
- "name": "优书网 - 書籍分類",
- "author": "skofkyo",
- "example": "https://www.yousuu.com/booklists/?type=man",
- "url": "^https?://www\\.yousuu\\.com/(bookstore|booklists)/",
- "action": 1,
- "waitElement": [
- "",
- ".loadingBlock"
- ],
- "init": "setTimeout(()=>{document.querySelectorAll('label.tab').forEach(e=>{e.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});document.querySelectorAll('h1>span').forEach(e=>{e.setAttribute('onclick','setTimeout(()=>{location.reload()}, 100)')});},1000)",
- "nextLinkByJs": "let next=doc.querySelector('li.number.active+li.number');if(next)return location.origin+location.pathname+location.search.replace(/&page=\\d+$/,'')+'&page='+next.innerText",
- "pageElement": ".booklist-card",
- "replaceElement": ".pagination",
- "pageAction": "let ge=e=>document.querySelector(e);let gae=e=>document.querySelectorAll(e);let lsr=location.search.replace(/&page=\\d+$/,'');setTimeout(()=>{gae('.number:not(.active)').forEach(e=>{let ls=lsr+'&page='+e.innerText;let link=`location.href='${ls}'`;e.setAttribute('onclick',link)});let pb=ge('.btn-prev');let nb=ge('.btn-next');let c=ge('.number.active');let n=ge('.number.active+.number');if(n){let ls=lsr+'&page='+n.innerText;let link=`location.href='${ls}'`;nb.setAttribute('onclick',link)}if(c.innerText>1){let p=c.innerText-1;let ls=lsr+'&page='+p;let link=`location.href='${ls}'`;pb.setAttribute('onclick',link)}},200)",
- "pageBar": 0
-},
-{
- "name": "第一版主 - 阅读",
- "author": "skofkyo",
- "example": "https://www.33yydstxt426.com/35/35669/1668046.html",
- "url": "^https?://www\\.\\d+yydstxt\\d+\\.com/\\d+/\\d+/\\d+.html$",
- "action": 1,
- "nextLink": "//center[@class='chapterPages']/a[@class='curr']/following-sibling::a[1] | //a[text()='下一章>' and contains(@href,'html')]",
- "pageElement": ".neirong"
-},
{
"name": "www.shoujixs.net_手机小说 - 阅读",
"author": "skofkyo",
@@ -5269,33 +4241,6 @@
"pageElement": ".books>.bk",
"replaceElement": ".page"
},
-{
- "name": "69書吧 -閱讀",
- "author": "skofkyo",
- "example": "https://www.69shuba.pro/txt/38161/26369110",
- "url": "^https?://www\\.69shuba\\.pro/txt/\\d+/\\d+",
- "history": 2,
- "action": 1,
- "nextLink": "//a[text()='下一章']",
- "pageElement": ".txtnav",
- "replaceElement": "head>title",
- "pageBar": 0,
- "pageAction": "let gae=e=>document.querySelectorAll(e);let t=gae('.txtnav');if(t.length>10)t[0].remove()"
-},
-{
- "name": "次元姬小说 - 閱讀",
- "author": "skofkyo",
- "example": "https://www.ciyuanji.com/chapter/5077_2227754.html",
- "url": "^https?://www\\.ciyuanji\\.com/chapter/\\w+\\.htm",
- "action": 1,
- "history": 2,
- "nextLink": "//a[button[text()='下一章']]",
- "pageElement": "[class^=chapter_title],[class^=chapter_list],[class^=chapter_article]",
- "replaceElement": "head>title,[class^='chapter_footer']",
- "pageAction": "let gae=e=>document.querySelectorAll(e);let h=gae('[class^=chapter_title]');let t=gae('[class^=chapter_article]');let l=gae('[class^=chapter_list]');if(t.length>10){h[0].remove();t[0].remove();l[0].remove()}",
- "pageBar": 0,
- "css": "[class^=chapter_article]+[class^=chapter_title]{padding-top:0px!important}"
-},
{
"name": "轻小说文库 - 閱讀",
"author": "skofkyo",
@@ -5311,31 +4256,6 @@
"pageAction": "let gae=e=>document.querySelectorAll(e);let h=gae('#title');let t=gae('#content');if(t.length>10){h[0].remove();t[0].remove()}",
"pageBar": 0
},
-{
- "name": "稷下書院 - 閱讀",
- "author": "skofkyo",
- "example": "https://www.novel543.com/1004298677/8001_1.html",
- "url": "^https?://www\\.novel543\\.com/\\d+/\\w+\\.html",
- "history": 2,
- "pinUrl": true,
- "init": "let ge=e=>document.querySelector(e);let h=ge('h1');h.innerText=h.innerText.split('-')[1].trim();let c=ge('.content');c.innerHTML=c.innerHTML.replace(/[^\\u4e00-\\u9fa5]+( )?/,' ').replace(/[^\\u4e00-\\u9fa5]+$/,'');let ad=ge('.gadBlock,.adBlock');if(ad){ad.remove()}c.innerHTML=c.innerHTML.replace(/ /g,' ');",
- "nextLink": "//a[text()='下一章' and not(contains(@href,'end'))]",
- "pageElement": "h1,.content",
- "replaceElement": "head>title,.is-active,.foot-nav",
- "pageInit": "let ge=e=>doc.querySelector(e);let h=ge('h1');h.innerText=h.innerText.split('-')[1].trim();let c=ge('.content');c.innerHTML=c.innerHTML.replace(/[^\\u4e00-\\u9fa5]+( )?/,' ').replace(/[^\\u4e00-\\u9fa5]+$/,'');let ad=ge('.gadBlock,.adBlock');if(ad){ad.remove()}c.innerHTML=c.innerHTML.replace(/ /g,' ');",
- "pageAction": "let gae=e=>document.querySelectorAll(e);gae('amp-addthis').forEach(e=>{e.remove()});let h=gae('h1');let t=gae('.content');if(t.length>10){h[0].remove();t[0].remove()}",
- "pageBar": 0,
- "css": ".gadBlock,.adBlock{display:none!important}#read h1{padding:20px 0 0px!important}"
-},
-{
- "name": "稷下書院 - 分類",
- "author": "skofkyo",
- "example": "https://www.novel543.com/bookstack/",
- "url": "^https?://www\\.novel543\\.com/",
- "nextLink": ".next>a",
- "pageElement": ".list>li",
- "replaceElement": ".pagination"
-},
{
"name": "天天看小說 - 顯示全部目錄",
"author": "skofkyo",
@@ -5350,7 +4270,7 @@
{
"name": "天天看小說 - 閱讀",
"author": "skofkyo",
- "example": "https://tw.bg3.co/novel/pagea/yedemingmingshu-huishuohuadezhouzi_1.html",
+ "example": "https://tw.ttkan.co/novel/pagea/yedemingmingshu-huishuohuadezhouzi_1.html",
"url": "^https?://[^/]+/novel/pagea/[^.]+\\.html",
"include": "//title[contains(text(),'天天看小說') or contains(text(),'天天看小说')]",
"action": 1,
@@ -5387,15 +4307,16 @@
{
"name": "無限小說 - 閱讀",
"author": "skofkyo",
- "example": "https://www.8book.com/read/125687/?312407",
- "url": "^https?://(www\\.)?8book\\.com/read/",
+ "example": "https://finance.binaccount.com/read/125687/?335030",
+ "url": "/read/",
+ "include": "//title[contains(text(),'無限小說')]",
"action": 1,
"history": 2,
"init": "setTimeout(()=>{let t=document.querySelector('#text');t.innerHTML=t.innerHTML.replace(/[ ]{4}[⒏88⒏⑧⑻ВbbьOσoоοoKkкcсcmmм.。·.]{9,10}/gi,'')},1000)",
"nextLink": "//a[text()='下一頁']|//a[text()='下一篇']",
"pageElement": "//div[div/@id='subtitle'] | id('text')",
"waitElement": [
- "#text>br"
+ "#pch,#ppbt,#nch,#npbt"
],
"replaceElement": ".read_btn_gp",
"pageInit": "let t=doc.querySelector('#text');t.innerHTML=t.innerHTML.replace(/[ ]{4}[⒏88⒏⑧⑻ВbbьOσoоοoKkкcсcmmм.。·.]{9,10}/gi,'')",
@@ -5443,8 +4364,8 @@
{
"name": "愛下電子書 - 閱讀",
"author": "skofkyo",
- "example": "https://ixdzs8.tw/read/38804/p1.html",
- "url": "^https?://ixdzs8\\.tw/read/\\d+/\\w+\\.html",
+ "example": "https://ixdzs.tw/read/38804/p1.html",
+ "url": "^https?://ixdzs\\.tw/read/\\d+/\\w+\\.html",
"history": 2,
"nextLink": "a.chapter-paging.chapter-next",
"pageElement": "#page .page-content",
@@ -5455,8 +4376,8 @@
{
"name": "愛下電子書 - 書籍列表",
"author": "skofkyo",
- "example": "https://ixdzs8.tw/sort/1/",
- "url": "^https?://ixdzs8\\.tw/(sort|hot|end)/",
+ "example": "https://ixdzs.tw/sort/1/",
+ "url": "^https?://ixdzs\\.tw/(sort|hot|end)/",
"nextLink": "a.num.current+a",
"pageElement": ".u-list",
"replaceElement": "div.panel+div>.pagei"
@@ -5508,13 +4429,13 @@
"id('pnnext')|id('navbar navcnt nav')//td[span]/following-sibling::td[1]/a|id('nn')/parent::a",
"id('pnprev')|id('navbar navcnt nav')//td[span]/following-sibling::td[1]/a|id('nn')/parent::a"
],
- "pageElement": "id('rso')|id('center_col')/style[contains(.,'relative')][id('rso')]|id('search')/div/div/style[1]",
+ "pageElement": "id('rso')|id('center_col')/style[contains(.,'relative')]",
"action": 1,
"pageNum": "&start={10*($p-1)}",
"pageBarTop": 55,
"url": "^https?://[^./]+\\.google(?:\\.[^./]{2,3}){1,2}/(?:c(?:se|ustom)|search|webhp|m|#)",
"replaceElement": "[role='navigation']>[role='presentation']",
- "css": "ol>li{display: inline-flex;}"
+ "css": "inIframe:#searchform,[data-l],[data-is-desktop]{display:none;}"
},
{
"name": "Google Trends",
@@ -5554,6 +4475,15 @@
"pageElement": "body>*",
"css": "div.sect1{position:static;overflow-wrap: break-word;}div.navheader{position: relative;}"
},
+{
+ "name": "Форум",
+ "url": "^https?://www\\.linux\\.org\\.ru/forum/",
+ "example": "https://www.linux.org.ru/forum/linux-hardware/16844066",
+ "nextLink": "strong+a,a[rel='next']",
+ "pinUrl": true,
+ "pageElement": "article",
+ "include": ".nav>.page-number"
+},
{
"name": "Standards DOC",
"url": "\\.html$",
@@ -5578,7 +4508,7 @@
"action": 1,
"url": "^https://.*\\.bing\\.com/search",
"nextLink": "a[title='Next page'],a.sb_pagN,a.sb_halfnext,a.sb_fullnpl",
- "pageElement": "body>style,ol#b_results>li.b_algo",
+ "pageElement": "ol#b_results>li.b_algo",
"waitElement": [
"a[title='Next page'],a.sb_pagN,a.sb_halfnext,a.sb_fullnpl,#b_results>.b_no",
".siteicon>div,div.rms_iac"
@@ -5618,10 +4548,11 @@
"url": "^https://www\\.pixiv\\.net/",
"example": "https://www.pixiv.net/tags/%E5%A5%B3%E3%81%AE%E5%AD%90/illustrations",
"action": 2,
- "pageElement": "section div>ul,div.sc-l7cibp-0.juyBTC>*,div.sc-1eop7y7-0.cJYTWr>*",
+ "pageElement": "section div>ul,div.sc-l7cibp-0.juyBTC>*,div.sc-1eop7y7-0.cJYTWr>*,ul.sc-9y4be5-1.jtUPOE",
"nextLink": "a[class*='filterProps-Styled-Component'][aria-disabled='false']:last-child",
"wait": 500,
"fitWidth": false,
+ "listenUrlChange": true,
"css": "@media (min-width: 1000px) {@supports (display:grid) {.krFoBL { grid-template-columns: repeat(6, 184px); }}}"
},
{
@@ -5630,11 +4561,12 @@
"pageElement": "#searchResultBox"
},
{
- "name": "Startpage",
- "url": "^https://www\\.startpage\\.com/",
- "pageElement": "section.w-gl>div.w-gl__result",
- "nextLink": "button.next",
- "action": 0
+ "name": "Startpage Search Results",
+ "url": "^https?://www\\.startpage\\.com/",
+ "example": "https://www.startpage.com/sp/search?query=pagetual",
+ "nextLink": "#main > div.pagination-container > div.pagination > form[aria-label='page Next'] > button",
+ "pageElement": "#main>.w-gl>div",
+ "action": 1
},
{
"name": "图书书目检索",
@@ -5777,7 +4709,7 @@
"a.prev"
],
"pageNum": "\\-\\d+\\-{$p}\\.html",
- "pageElement": "div#threadlist form",
+ "pageElement": "div#threadlist>div>form",
"replaceElement": "#pgt div.pg"
},
{
@@ -5805,14 +4737,15 @@
"name": "FC Portables",
"url": "^https://www\\.fcportables\\.com",
"pageElement": ".listing-blog>article",
- "pageAction": "eles.forEach(e=>{let a=e.querySelector('.img-holder');if(!a)return;a.style.backgroundImage=`url(\"${a.dataset.src}\")`;a.classList.add('b-loaded')})"
+ "pageAction": "eles.forEach(e=>{let a=e.querySelector('.img-holder[data-src]');if(!a)return;a.style.backgroundImage=`url(\"${a.dataset.src}\")`;a.classList.add('b-loaded')})"
},
{
"name": "1688全部商品页",
"url": "^https://.*\\.1688\\.com/page",
"pageElement": "#bd_1_container_0 > div:nth-of-type(1) > div:nth-of-type(2) > div:nth-of-type(6) > div",
- "pageAction": "window.setUrl=null;window.index=0;eles.forEach(e=>{let img=e.querySelector('.main-picture[src^=data]');if(!img)return;img.src=img.nextElementSibling.children[0].src;e.onclick=()=>window.open(e.dataset.url,'_blank')})",
- "pageInit": "if(!window.index)window.index=0;if(!window.setUrl){window.setUrl=()=>{setTimeout(()=>{if(window.url){eles[window.index++].dataset.url=window.url;window.url=null;}if(eles[window.index]){eles[window.index].click();window.setUrl()}},1)};Object.defineProperty(doc.defaultView, 'open', { get: function () { return (s)=>window.url=s; } });window.setUrl();}if(eles.length<=window.index)return true;else return false;"
+ "pageAction": "window.setUrl=null;window.index=0;eles.forEach(e=>{e.onclick=()=>window.open(e.dataset.url,'_blank');})",
+ "pageInit": "if(!window.index)window.index=0;if(!window.setUrl){window.setUrl=()=>{setTimeout(()=>{if(window.url){eles[window.index++].dataset.url=window.url;window.url=null;}if(eles[window.index]){eles[window.index].click();window.setUrl()}},1)};Object.defineProperty(doc.defaultView, 'open', { get: function () { return (s)=>window.url=s; } });window.setUrl();}if(eles.length<=window.index)return true;else return false;",
+ "waitElement":"!.main-picture[src^=data]"
},
{
"name": "blog1",
@@ -5833,15 +4766,31 @@
"name": "Baidu",
"insertPos": 1,
"nextLink": [
- "//*[@id=\"page\"]/div/a[contains(text(),'下')]",
- "//*[@id=\"page\"]/div/a[contains(text(),'上')]"
+ "//*[@id='page']/div/a[span[contains(text(),'下')]]",
+ "//*[@id='page']/div/a[span[contains(text(),'上')]]"
],
- "pageElement": "//*[@id=\"content_style\"]|//*[@id=\"content_left\"]/*",
+ "pageElement": "//*[@id=\"content_style\"]/style/following-sibling::*|//*[@id=\"content_left\"]/*",
"pageNum": "&pn={10*($p-1)}",
"url": "^https?://www\\.baidu\\.com/(s|baidu)\\b.",
"pageBarTop": 75,
"replaceElement": "#page",
- "exclude": ".AC-style-logo",
+ "exclude": ".AC-style-logo,.killRight,a.new-nextpage-only,a.new-nextpage",
+ "wait": 500
+},
+{
+ "name": "Baidu",
+ "insertPos": 1,
+ "nextLink": [
+ "//*[@id='page']/div/a[span[contains(text(),'下')]]",
+ "//*[@id='page']/div/a[span[contains(text(),'上')]]"
+ ],
+ "pageElement": "//*[@id=\"content_style\"]|//*[@id=\"content_left\"]",
+ "pageNum": "&pn={10*($p-1)}",
+ "url": "^https?://www\\.baidu\\.com/(s|baidu)\\b.",
+ "pageBar": 0,
+ "replaceElement": "#page",
+ "exclude": ".AC-style-logo,a.new-nextpage-only,a.new-nextpage",
+ "include": ".killRight",
"wait": 500
},
{
@@ -5856,7 +4805,7 @@
"pageBar": "pageBar.classList.add('j_thread_list');pageBar.dataset.field='{}'",
"url": "^https?://tieba\\.baidu\\.com/.+",
"pageElement": "ul#thread_list>li",
- "pageNum": "&pn={50*($p-1)}",
+ "pageNum": "[\\?&]pn={50*($p-1)}",
"nextLink": ".next.pagination-item "
},
{
@@ -5865,7 +4814,7 @@
"nextLink": "//div[@class=\"pb_footer\"]//a[starts-with(text(), '下一页')]",
"pageElement": "//div[@class=\"p_postlist\"]/div[starts-with(@class, 'l_post')]",
"action": 1,
- "pageNum": "&pn={$p}",
+ "pageNum": "[\\?&]pn={$p}",
"url": "^https?://tieba\\.baidu\\.com/p/.+",
"wait": "if(doc==document)return true;let lzl=doc.querySelector('div.hideLzl');if(lzl){var actualTop=lzl.offsetTop;var current=lzl.offsetParent;while(current!==null){actualTop+=current.offsetTop;current=current.offsetParent;}doc.body.scrollTop=actualTop;doc.documentElement.scrollTop=actualTop;return false}else{return true}",
"history": 0
@@ -6124,7 +5073,8 @@
"action": 1,
"url": "^https://search\\.bilibili\\.com",
"pageElement": "ul>li.video-item,div.video-list.row>*",
- "sandbox": false
+ "sandbox": false,
+ "waitElement": ".bili-video-card__wrap"
},
{
"name": "bilibili space",
@@ -6162,17 +5112,18 @@
"name": "魂+",
"url": "^https?://((www\\.|bbs\\.)?(south|north|level|white|soul|snow|east|spring|summer|blue)-plus.(net|org)|bbs.imoutolove.me)/",
"action": 1,
- "sleep": 1000
+ "sleep": 1000,
+ "exclude": "//div[@id='main']/form|//tr[@align='center']"
},
{
"name": "魂+阅读页",
"url": "^https?://((www\\.|bbs\\.)?(south|north|level|white|soul|snow|east|spring|summer|blue)-plus.(net|org)|bbs.imoutolove.me)/",
"action": 1,
"type": 0,
- "pageElement": "//div[@id='main']/form",
+ "pageElement": "//div[@id='main']/form[1]",
"nextLink": "//div[@class='pages']/ul/li[.//b]/following-sibling::li/a",
"sleep": 1000,
- "pageNum": "page-{$p}.html"
+ "pageNum": "-page-{$p}.html"
},
{
"name": "魂+列表页",
@@ -6182,7 +5133,7 @@
"pageElement": "//tr[@align='center']",
"nextLink": "//div[@class='pages']/ul/li[.//b]/following-sibling::li/a",
"sleep": 1000,
- "pageNum": "page-{$p}.html"
+ "pageNum": "-page-{$p}.html"
},
{
"name": "动漫啦",
@@ -6194,6 +5145,13 @@
"insert": ".lazyBox",
"insertPos": 2
},
+{
+ "name": "Fur Affinity",
+ "url": "^https?://www\\.furaffinity\\.net/(?:browse|msg/submissions|(?:favorites|gallery|scraps)/[^/]+)/",
+ "pageElement": "//section[@class='gallery s-200 ']/*",
+ "nextLink": "//form[@name='replyform']/button[@value='Next']",
+ "action": 0
+},
{
"name": "bookmarkearth",
"action": 0,
@@ -6233,7 +5191,7 @@
},
{
"name": "什么值得买社区",
- "action": 0,
+ "action": 1,
"url": "^https://post\\.smzdm\\.com/p",
"pageElement": "#comment",
"nextLink": ".pagedown>a"
@@ -6402,7 +5360,8 @@
"nextLink": "a[title='下一页']",
"action": 2,
"pageElement": "div#m_posts",
- "pageAction": "doc&&doc.addEventListener('mouseover',e=>{e.preventDefault();e.stopPropagation()},true)"
+ "pageAction": "doc&&doc.addEventListener('mouseover',e=>{e.preventDefault();e.stopPropagation()},true)",
+ "iframeInit": "win.self=win.top;"
},
{
"name": "NGA列表页",
@@ -6532,13 +5491,21 @@
"pageNum": "start={100*($p-1)}"
},
{
- "name": "Github issues and pulls",
- "type": 0,
+ "name": "Github issues",
+ "action": 0,
+ "url": "^https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/issues",
+ "pageElement": "[data-listview-component=items-list]>[class^=ListItems]",
+ "nextLinkByUrl": [
+ "&page=(\\d+)",
+ "&page={$1+1}"
+ ]
+},
+{
+ "name": "Github pulls",
"action": 0,
- "url": "^https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/(?:issues|pulls)",
+ "url": "^https:\\/\\/github\\.com\\/[^/]+\\/[^/]+\\/pulls",
"pageElement": "//div[starts-with(@id,'issue_')]",
- "nextLink": "//a[@class='next_page']",
- "pinUrl": true
+ "nextLink": "//a[rel=next]"
},
{
"name": "Repository search results · GitHub",
@@ -6552,6 +5519,14 @@
"action": 0,
"include": "[rel='next']"
},
+{
+ "name": "github repos list",
+ "url": "^https?://github\\.com/[^/]+\\?tab=repositories",
+ "pageElement": "//ul[@data-filterable-for='your-repos-filter']",
+ "nextLink": "//a[@rel='next']",
+ "action": 0,
+ "css": ".starring-container+.hide-lg{display:none}"
+},
{
"name": "Actions · github",
"action": 0,
@@ -7045,7 +6020,7 @@
},
{
"name": "Google cse",
- "url": "^(https://www\\.lukol\\.com|https://www\\.searchcraigslist\\.net|https://cse\\.google\\.com.*&gsc\\.q=)",
+ "url": "^(https://www\\.lukol\\.com|https://www\\.searchcraigslist\\.net)|&gsc\\.q=",
"pageElement": ".gsc-expansionArea>.gsc-result",
"nextLink": ".gsc-cursor-current-page+div",
"wait": 500
@@ -7183,6 +6158,32 @@
"action": 3,
"pageElement": "ul.DiscussionList-discussions>li"
},
+{
+ "name": "All Discussions - Orion Public Issue Tracker",
+ "url": "^https?://orionfeedback\\.org/(\\?|$)",
+ "example": "https://orionfeedback.org/?page=3",
+ "action": 3
+},
+{
+ "name": "RuTracker.org",
+ "url": "^https?://rutracker\\.org/forum/",
+ "example": "https://rutracker.org/forum/viewtopic.php?t=239577",
+ "pageElement": "table.topic"
+},
+{
+ "name": "骑砍中亚",
+ "url": "^https?://h5\\.shaoniandream\\.com/pages/chapter/",
+ "example": "https://h5.shaoniandream.com/pages/chapter/index?bookid=1866",
+ "nextLink": "//uni-view[text()=\"下一章\"]"
+},
+{
+ "name": "挥剑诗篇",
+ "url": "^https?://hlib\\.cc/s/",
+ "example": "https://hlib.cc/s/7301114",
+ "nextLink": ".btn.active~a",
+ "pageElement": ".col-lg-9 .list-group-item",
+ "action": 0
+},
{
"name": "Sanfoundry",
"url": "^https?://www\\.sanfoundry\\.com/",
@@ -7212,6 +6213,17 @@
"nextLink": "a.next.page-numbers",
"pageElement": "main.site-main > div.row.posts-wrapper"
},
+{
+ "name": "Konachan-CHS 汉化 | 动漫壁纸下载 | Konachan中文站",
+ "url": "^https?://gelbooru\\.wjcodes\\.com/",
+ "nextLink": "//ul[@class='am-pagination']/li/a[text()='下一页']"
+},
+{
+ "name": "投稿列表 pixivFANBOX",
+ "url": "^https?://[^\\.]+\\.fanbox\\.cc/",
+ "example": "https://ffxivinitiala.fanbox.cc/posts",
+ "waitElement": "!.gaaMeK,img[class^=LazyImage]:not([src]),[class^=LazyImage__LoadingIcon]"
+},
{
"name": "游戏怀旧灌水首页禁用",
"url": "^https?://www\\.yxhjgs\\.com/$",
@@ -7222,12 +6234,6 @@
"url": "^https?://jump\\d?\\.bdimg\\.com/safecheck",
"enable": 0
},
-{
- "name": "检测到AC百度就不运行",
- "url": ".",
- "pageElement": ".AC-style-logo",
- "enable": 0
-},
{
"name": "pan.baidu",
"url": "^https?://.*pan\\.baidu\\.com",
@@ -7353,6 +6359,24 @@
"url": "^https?://www\\.pexels\\.com/",
"enable": 0
},
+{
+ "name": "stripe",
+ "url": "^https?://js\\.stripe\\.com/",
+ "enable": 0
+},
+{
+ "name": "cardinalcommerce",
+ "url": "^https?://geoissuer\\.cardinalcommerce\\.com/",
+ "enable": 0
+},
+{
+ "name": "Slickdeals",
+ "url": "^https?://slickdeals\\.net/f/",
+ "include": ".slickdealsPagination",
+ "nextLink": "span+a.slickdealsPagination__pageNumber",
+ "action": 1,
+ "waitElement": ".slickdealsPagination>a"
+},
{
"name": "IGGGAMES » Free Download PC Games - Direct Links - Torrent",
"url": "^https?://igg-games\\.com/",
@@ -7453,5 +6477,26 @@
"action": 0,
"pageElement":".web-result>li",
"pagePre": "let evalData=response.match(/\\*{let ele=document.createElement('li');ele.innerHTML=`${item.title} `;eles.push(ele);});return eles;"
+},
+{
+ "name": "EpicentrK - Герметики та мастики",
+ "author": "epicentrkScraper",
+ "url": "^https?://epicentrk\\.ua/ua/shop/germetiki-i-silikony/.*$",
+ "example": "https://epicentrk.ua/ua/shop/germetiki-i-silikony/",
+ "nextlink": "div.pagination a.pagination__btn--next",
+ "replaceElement": "div.product-card",
+ "pageElement": "div.products-catalog__list",
+ "action": 2
+},
+{
+ "name": "xHamster",
+ "url": "^https://([\\w]+\\.)?(xhamster|xhaccess|xhamster19)\\.(com|desi)/",
+ "author": "vieller",
+ "pageElement": "div:has(+ *[data-role*='pagination']), div:has(+ *[class*='pager-section']), div:has(+ *[class*='pagination-'])",
+ "nextLink": "a[data-page='next'], a[rel='next']",
+ "action": 1,
+ "init": "let candidates=Array.from(document.querySelectorAll('.thumb-list__item'));let bestCandidate=candidates.find(c=>c.querySelector('[data-role=\"video-duration\"]'));if(!bestCandidate&&candidates.length) bestCandidate=candidates[0];if(!window._pagetualMasterTemplateVideo){if(bestCandidate){let clone=bestCandidate.cloneNode(true);let badgeElements=clone.querySelectorAll('[data-role=\"video-watched\"], [data-brand=\"full video\"]');badgeElements.forEach(badge=>badge.remove());let xhIcons=clone.querySelectorAll('.xh-icon');xhIcons.forEach(icon=>icon.remove());window._pagetualMasterTemplateVideo=clone.innerHTML;let durationSpan=clone.querySelector('[data-role=\"video-duration\"] [class*=\"tiny-\"]');if(durationSpan){let tinyClass=Array.from(durationSpan.classList).find(c=>c.startsWith('tiny-'));if(tinyClass){let suffix=tinyClass.split('-').pop();if(suffix) window._pagetualSuffix=suffix;}}}} if(!window._pagetualMasterGallery){let galleryCandidates=Array.from(document.querySelectorAll('[class*=\"container-\"] > [class*=\"wrapper\"]'));if(!galleryCandidates.length) galleryCandidates=Array.from(document.querySelectorAll('div[class*=\"wrapper\"]')).filter(el=>el.querySelector('[class*=\"author-\"]'));let bestGallery=galleryCandidates.find(g=>g.querySelector('[class*=\"author-\"]'));if(!bestGallery&&galleryCandidates.length) bestGallery=galleryCandidates[0];if(bestGallery){let clone=bestGallery.cloneNode(true);window._pagetualMasterGallery=clone.innerHTML;let captionSpan=clone.querySelector('[class*=\"caption-\"]');if(captionSpan){let captionClass=Array.from(captionSpan.classList).find(c=>c.startsWith('caption-'));if(captionClass) window._pagetualCaptionSuffix=captionClass.split('-').pop();} let bodySpan=clone.querySelector('[class*=\"body-bold-\"]');if(bodySpan){let bodyClass=Array.from(bodySpan.classList).find(c=>c.startsWith('body-bold-'));if(bodyClass) window._pagetualBodySuffix=bodyClass.split('-').pop();}}} if(!window._pagetualSuffix) window._pagetualSuffix='8643e';if(!window._pagetualCaptionSuffix) window._pagetualCaptionSuffix='8643e';if(!window._pagetualBodySuffix) window._pagetualBodySuffix='8643e';if(!window._pagetualFriendsOnlyTemplate){let rootClass='root-'+window._pagetualSuffix;let iconClass='icon-'+window._pagetualSuffix;window._pagetualFriendsOnlyTemplate=`Friends only
`;}",
+ "pageInit": "let container = eles[0]; if (!container) return; /* Extract data from window.initials and handle different page types */ let script = doc.querySelector('script#initials-script'); if (!script) { script = Array.from(doc.querySelectorAll('script')).find(s => s.textContent.includes('window.initials='));} if (!script) return; let scriptText = script.textContent; let match = scriptText.match(/window\\.initials\\s*=\\s*(\\{[\\s\\S]*?\\});/); if (!match) return; let jsonStr = match[1]; let initials; try { initials = eval('(' + jsonStr + ')');} catch (e) { return;} /* Regular photo gallery (no hydration, remove skeleton overlays only) */ let skeletonSelector = 'a[class*=\"cover\"] > div[class*=\"container-\"][class*=\"primaryColor-\"]'; let loadingSkeleton = container.querySelector(skeletonSelector); /* if (initials.photosPage !== undefined || initials.galleryPage !== undefined) { */ if (loadingSkeleton) { let galleryItemSelector = 'div[class*=\"wrapper\"], div[style]:not([class])'; let galleryItems = container.querySelectorAll(galleryItemSelector); for (let ele of galleryItems) { /* let skeleton = ele.querySelector('a[class*=\"cover\"] > div[class*=\"container-\"][class*=\"primaryColor-\"]'); */ let skeleton = ele.querySelector(skeletonSelector); if (skeleton && skeleton.querySelector('span[class*=\"dot\"]')) { skeleton.remove();}} return;} function round(value, precision) { let multiplier = Math.pow(10, precision || 0); return Math.round(value * multiplier) / multiplier;} function formatViews(v) { if (v >= 1e6) return round(v / 1e6, 1) + 'M'; if (v >= 1e3) return round(v / 1e3, 1) + 'K'; return v.toString();} /* Heuristics: locate photo gallery metadata array in initials */ function findPhotoItems(initials, expectedCount, tolerance = 2) { function search(obj, targetLen, depth = 0) { if (depth > 12) return null; if (!obj || typeof obj !== 'object') return null; if (Array.isArray(obj) && obj.length === targetLen && obj.length > 0) { let first = obj[0]; if (first && typeof first === 'object') { let hasPhotoProps = ('pageURL' in first || 'imageURL' in first) && ('titleLocalized' in first || 'title' in first) && ('imgCount' in first || 'views' in first); if (hasPhotoProps) return obj;}} for (let k in obj) { if (obj.hasOwnProperty(k)) { let result = search(obj[k], targetLen, depth + 1); if (result) return result;}} return null;} let exactMatch = search(initials, expectedCount); if (exactMatch) return exactMatch; for (let delta = -tolerance; delta <= tolerance; delta++) { if (delta === 0) continue; let len = expectedCount + delta; if (len <= 0) continue; let match = search(initials, len); if (match) return match;} return null;} /* Generic photo gallery hydration (heuristics-based) */ let photoItemSelector = 'div[class*=\"container-\"] > div[class*=\"wrapper-\"], div[class*=\"container-\"] > div[class*=\"default-\"]'; let photoItems = container.querySelectorAll(photoItemSelector); if (photoItems.length && window._pagetualMasterGallery) { let items = findPhotoItems(initials, photoItems.length, 4); if (items?.length) { let inner = window._pagetualMasterGallery; for (let i = 0; i < photoItems.length && i < items.length; i++) { let ele = photoItems[i]; let data = items[i]; let div = document.createElement('div'); div.innerHTML = inner; let coverLink = div.querySelector('a[class*=\"coverLink-\"]'); if (coverLink && data.pageURL) { coverLink.href = data.pageURL;} let img = div.querySelector('img[class*=\"cover-\"]'); if (img) { img.src = data.imageURL; img.srcset = data.thumbURL; img.alt = data.titleLocalized || '';} let titleLink = div.querySelector('[class*=\"title-\"]'); if (titleLink && data.pageURL) { titleLink.href = data.pageURL; titleLink.textContent = data.titleLocalized || '';} let authorContainer = div.querySelector('[class*=\"author-\"]'); if (authorContainer && data.author) { authorContainer.href = data.author.link; let nameSpan = authorContainer.querySelector('[class*=\"name-\"]'); if (nameSpan) { nameSpan.textContent = data.author.name;}} let avatarImg = div.querySelector('[class*=\"avatar-\"] img'); if (avatarImg && data.author && data.author.img) { avatarImg.src = data.author.img; avatarImg.alt = data.author.name;} let photoSpan = div.querySelector('[class*=\"caption\"][class*=\"label\"]'); if (photoSpan) photoSpan.textContent = data.imgCount; let viewsSpan = div.querySelector('[class*=\"viewsText-\"]'); if (viewsSpan) viewsSpan.textContent = formatViews(data.views) + ' views'; while (ele.firstChild) ele.removeChild(ele.firstChild); while (div.firstChild) ele.appendChild(div.firstChild);} return;}} /* Heuristics: locate video metadata array in initials */ function findVideoProps(obj, depth) { if (depth > 10) return null; if (!obj || typeof obj !== 'object') return null; if (Array.isArray(obj) && obj.length > 0) { let first = obj[0]; if (first && typeof first === 'object' && 'id' in first && 'duration' in first && 'title' in first && 'pageURL' in first && 'views' in first) { return obj;}} for (let k in obj) if (obj.hasOwnProperty(k)) { let r = findVideoProps(obj[k], depth + 1); if (r) return r;} return null;} function formatDuration(s) { let h = Math.floor(s / 3600), m = Math.floor((s % 3600) / 60), sec = s % 60; if (h) return h + ':' + (m < 10 ? '0' + m : m) + ':' + (sec < 10 ? '0' + sec : sec); return m + ':' + (sec < 10 ? '0' + sec : sec);} /* Generic video page hydration (heuristics-based) */ let videoSelector = 'div[class*=\"thumb-list__item\"]:not([class*=\"loading\"])'; let videoItems = container.querySelectorAll(videoSelector); if (videoItems.length && window._pagetualMasterTemplateVideo) { let props = findVideoProps(initials, 0); if (props?.length) { let inner = window._pagetualMasterTemplateVideo; for (let ele of videoItems) { let id = ele.getAttribute('data-video-id'); if (!id) continue; let data = props.find(p => p.id == id); if (!data) continue; let div = document.createElement('div'); div.innerHTML = inner; let noscripts = div.querySelectorAll('noscript'); for (let ns of noscripts) ns.remove(); let link = div.querySelector('a[data-role=\"thumb-link\"]'); if (link && data.pageURL) { link.href = data.pageURL; link.setAttribute('data-previewvideo', data.trailerURL || ''); link.setAttribute('aria-label', data.title || '');} let img = div.querySelector('img.thumb-image-container__image'); if (img) { if (data.icon === 'friends') { let thumbContainer = div.querySelector('[class*=\"thumb-image-container\"]') || img.parentElement; img.remove(); if (thumbContainer && window._pagetualFriendsOnlyTemplate) { thumbContainer.insertAdjacentHTML('beforeend', window._pagetualFriendsOnlyTemplate);}} else { img.src = data.imageURL; img.srcset = data.thumbURL; img.alt = data.title || '';}} let sprite = div.querySelector('.thumb-image-container__sprite'); if (sprite) { sprite.setAttribute('data-sprite', data.spriteURL || ''); sprite.id = id;} let durationSpan = div.querySelector('[data-role=\"video-duration\"] [class*=\"tiny-\"]'); if (durationSpan) durationSpan.textContent = formatDuration(data.duration); let titleLink = div.querySelector('.video-thumb-info__name'); if (titleLink && data.pageURL) { titleLink.href = data.pageURL; titleLink.title = data.title || ''; titleLink.textContent = data.title || '';} let uploaderData = div.querySelector('.video-uploader-data'); if (uploaderData) { if (data.landing && data.landing.name) { let logo = uploaderData.querySelector('.video-uploader-logo'); if (logo && data.landing.link) { logo.href = data.landing.link; logo.textContent = data.landing.name.charAt(0).toUpperCase();} let name = uploaderData.querySelector('.video-uploader__name'); if (name && data.landing.link) { name.href = data.landing.link; name.textContent = data.landing.name;}} else { let logo = uploaderData.querySelector('.video-uploader-logo'); if (logo) logo.remove(); let name = uploaderData.querySelector('.video-uploader__name'); if (name) name.remove(); let sep = uploaderData.querySelector('.video-thumb-uploader__separator'); if (sep) sep.remove();}} let viewsSpan = div.querySelector('.video-thumb-views'); if (viewsSpan) viewsSpan.textContent = formatViews(data.views) + ' views'; let onVideo = div.querySelector('.thumb-image-container__on-video'); if (onVideo) onVideo.style.zIndex = '20'; if (data.isWatched) { if (onVideo && !onVideo.querySelector('.thumb-image-container__watched')) { let w = document.createElement('div'); w.className = 'thumb-image-container__watched'; w.setAttribute('data-role', 'video-watched'); let tinyBold = 'tiny-bold-' + window._pagetualSuffix; let invert = 'invert-' + window._pagetualSuffix; w.innerHTML = `Watched
`; if (onVideo.firstChild) onVideo.insertBefore(w, onVideo.firstChild); else onVideo.appendChild(w);}} if (data.hasProducerBadge) { let a = div.querySelector('a[data-role=\"thumb-link\"]'); if (a && !a.querySelector('.thumb-image-container__badge')) { let b = document.createElement('div'); b.className = 'thumb-image-container__badge'; b.setAttribute('data-role-producer-badge', ''); b.setAttribute('data-brand', 'full video'); b.innerHTML = ' '; a.appendChild(b);}} while (ele.firstChild) ele.removeChild(ele.firstChild); while (div.firstChild) ele.appendChild(div.firstChild);}}}",
+ "pageAction": "if(!window._pagetualVideoPreviewAdded){window._pagetualVideoPreviewAdded=true;document.body.addEventListener('mouseenter',(e)=>{let anchor=e.target.closest('a[data-role=\"thumb-link\"]');if(!anchor) return;let trailerUrl=anchor.getAttribute('data-previewvideo');if(!trailerUrl) return;if(anchor._videoElem) return;if(getComputedStyle(anchor).position!=='relative') anchor.style.position='relative';let videoElem=Object.assign(document.createElement('video'),{src:trailerUrl,loop:true,muted:true,autoplay:true,playsInline:true});Object.assign(videoElem.style,{position:'absolute',top:0,left:0,width:'100%',height:'100%',objectFit:'cover',zIndex:10,pointerEvents:'none',backgroundColor:'black'});anchor.appendChild(videoElem);videoElem.play().catch(e=>console.warn('play error:',e));anchor._videoElem=videoElem;},true);document.body.addEventListener('mouseleave',(e)=>{let anchor=e.target.closest('a[data-role=\"thumb-link\"]');if(!anchor) return;let videoElem=anchor._videoElem;if(!videoElem) return;videoElem.pause();videoElem.remove();anchor._videoElem=null;},true);}"
}
]
diff --git a/Pagetual/version b/Pagetual/version
index 8f92bfdd497..e2a9fee008a 100644
--- a/Pagetual/version
+++ b/Pagetual/version
@@ -1 +1 @@
-35
+109
diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js
index 33f5f0a2d76..440b3e10f70 100644
--- a/Picviewer CE+/Picviewer CE+.user.js
+++ b/Picviewer CE+/Picviewer CE+.user.js
@@ -9,13 +9,13 @@
// @description Powerful picture viewing tool online, which can popup/scale/rotate/batch save pictures automatically
// @description:zh-CN 在线看图工具,支持图片翻转、旋转、缩放、弹出大图、批量保存
// @description:zh-TW 線上看圖工具,支援圖片翻轉、旋轉、縮放、彈出大圖、批量儲存
-// @description:ja オンラインで画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます
+// @description:ja 画像を強力に閲覧できるツール。ポップアップ表示、拡大・縮小、回転、一括保存などの機能を自動で実行できます
// @description:pt-BR Poderosa ferramenta de visualização de imagens on-line, que pode pop-up/dimensionar/girar/salvar em lote imagens automaticamente
// @description:ru Мощный онлайн-инструмент для просмотра изображений, который может автоматически отображать/масштабировать/вращать/пакетно сохранять изображения
-// @version 2024.6.26.2
+// @version 2026.2.6.1
// @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAMAAADXqc3KAAAAV1BMVEUAAAD////29vbKysoqKioiIiKysrKhoaGTk5N9fX3z8/Pv7+/r6+vk5OTb29vOzs6Ojo5UVFQzMzMZGRkREREMDAy4uLisrKylpaV4eHhkZGRPT08/Pz/IfxjQAAAAgklEQVQoz53RRw7DIBBAUb5pxr2m3/+ckfDImwyJlL9DDzQgDIUMRu1vWOxTBdeM+onApENF0qHjpkOk2VTwLVEF40Kbfj1wK8AVu2pQA1aBBYDHJ1wy9Cf4cXD5chzNAvsAnc8TjoLAhIzsBao9w1rlVTIvkOYMd9nm6xPi168t9AYkbANdajpjcwAAAABJRU5ErkJggg==
// @namespace https://github.com/hoothin/UserScripts
-// @homepage https://www.hoothin.com
+// @homepage https://pv.hoothin.com/
// @supportURL https://github.com/hoothin/UserScripts/issues
// @connect www.google.com
// @connect www.google.com.hk
@@ -46,10 +46,8 @@
// @grant GM.notification
// @grant unsafeWindow
// @require https://update.greasyfork.org/scripts/6158/23710/GM_config%20CN.js
-// @require https://update.greasyfork.org/scripts/438080/1400550/pvcep_rules.js
-// @require https://update.greasyfork.org/scripts/440698/1399329/pvcep_lang.js
-// @downloadURL https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.user.js
-// @updateURL https://greasyfork.org/scripts/24204-picviewer-ce/code/Picviewer%20CE+.meta.js
+// @require https://update.greasyfork.org/scripts/438080/1738227/pvcep_rules.js
+// @require https://update.greasyfork.org/scripts/440698/1740314/pvcep_lang.js
// @match *://*/*
// @exclude http://www.toodledo.com/tasks/*
// @exclude http*://maps.google.com*/*
@@ -57,7 +55,7 @@
// @exclude *://mega.*/*
// @exclude *://*.mega.*/*
// @exclude *://onedrive.live.com/*
-// @run-at document-body
+// @run-at document-end
// @created 2011-6-15
// @contributionURL https://ko-fi.com/hoothin
// @contributionAmount 1
@@ -65,7 +63,7 @@
if (window.top != window.self) {
try {
- if (window.self.innerWidth < 250 || window.self.innerHeight < 250) {
+ if ((window.self.innerWidth && window.self.innerWidth < 250) || (window.self.innerHeight && window.self.innerHeight < 250)) {
return;
}
} catch(e) {
@@ -11927,7 +11925,7 @@ var floatBar;
'use strict';
//var siteInfo = [{}];
- var debug;
+ var debug = console.log.bind(console);
var lang;
function initLang(){
let customLang=storage.getItem("customLang")||'auto';
@@ -11978,13 +11976,6 @@ ImgOps | https://imgops.com/#b#`;
}else{
_GM_setClipboard=(s)=>{};
}
- if(typeof GM_xmlhttpRequest!='undefined'){
- _GM_xmlhttpRequest=GM_xmlhttpRequest;
- }else if(typeof GM!='undefined' && typeof GM.xmlHttpRequest!='undefined'){
- _GM_xmlhttpRequest=GM.xmlHttpRequest;
- }else{
- _GM_xmlhttpRequest=(f)=>{fetch(f.url).then(response=>response.text()).then(data=>{let res={response:data};f.onload(res)}).catch(f.onerror())};
- }
if(typeof GM_registerMenuCommand!='undefined'){
_GM_registerMenuCommand=GM_registerMenuCommand;
}else if(typeof GM!='undefined' && typeof GM.registerMenuCommand!='undefined'){
@@ -12006,7 +11997,7 @@ ImgOps | https://imgops.com/#b#`;
_GM_xmlhttpRequest = GM.xmlHttpRequest;
GM_fetch = true;
} else {
- _GM_xmlhttpRequest = (f) => {fetch(f.url, {method: f.method || 'GET', body: f.data || '', headers: f.headers}).then(response => response.text()).then(data => {f.onload({response: data})}).catch(f.onerror())};
+ _GM_xmlhttpRequest = (f) => {fetch(f.url, (f.method && f.method !== 'GET' ? {method: f.method || 'GET', body: f.data || '', headers: f.headers} : {method: 'GET', headers: f.headers})).then(response => response.text()).then(data => {f.onload({response: data})}).catch(e => f.onerror())};
}
if (typeof GM_addStyle != 'undefined') {
_GM_addStyle = GM_addStyle;
@@ -12029,6 +12020,7 @@ ImgOps | https://imgops.com/#b#`;
method: (option && option.method) || 'GET',
url: url.trim(),
data: (option && option.body) || '',
+ cookie: cookie,
headers: (option && option.headers) || {
referer: url,
origin: url,
@@ -12063,6 +12055,186 @@ ImgOps | https://imgops.com/#b#`;
}
} else GM_fetch = fetch;
+ class ImageSizeFetcher {
+ constructor(gmXhr, config = {}) {
+ if (!gmXhr) throw new Error("GM_xmlhttpRequest is required");
+ this.gmXhr = gmXhr;
+ this.cache = new Map();
+ this.queue = [];
+ this.activeCount = 0;
+ this.concurrency = config.concurrency || 3;
+ this.timeout = config.timeout || 5000;
+ }
+
+ async getSize(url, options = {}) {
+ const { force = false, strategy = 'auto' } = options;
+ if (!url) return null;
+
+ if (!force && this.cache.has(url)) {
+ return this.cache.get(url);
+ }
+
+ if (url.startsWith('data:')) {
+ const size = this._calculateBase64Size(url);
+ this.cache.set(url, size);
+ return size;
+ }
+
+ if (url.startsWith('blob:')) {
+ return this._getBlobSize(url);
+ }
+
+ if (strategy === 'local-only' || strategy === 'auto') {
+ const perfSize = this._getFromPerformance(url);
+ if (perfSize !== null) {
+ this.cache.set(url, perfSize);
+ return perfSize;
+ }
+ if (strategy === 'local-only') return null;
+ }
+
+ return this._scheduleRequest(url);
+ }
+
+ _calculateBase64Size(dataUrl) {
+ const base64Str = dataUrl.split(',')[1];
+ if (!base64Str) return 0;
+ const len = base64Str.length;
+ const padding = (base64Str.match(/=/g) || []).length;
+ return (len * 3 / 4) - padding;
+ }
+
+ async _getBlobSize(blobUrl) {
+ try {
+ const response = await fetch(blobUrl);
+ const blob = await response.blob();
+ return blob.size;
+ } catch (e) {
+ console.error('Blob fetch failed', e);
+ return null;
+ }
+ }
+
+ _getFromPerformance(url) {
+ const entries = performance.getEntriesByName(url);
+ if (entries.length > 0) {
+ const entry = entries[entries.length - 1];
+ if (entry.decodedBodySize > 0) return entry.decodedBodySize;
+ if (entry.encodedBodySize > 0) return entry.encodedBodySize;
+ }
+ return null;
+ }
+
+ _scheduleRequest(url) {
+ return new Promise((resolve, reject) => {
+ this.queue.push({ url, resolve, reject });
+ this._processQueue();
+ });
+ }
+
+ _processQueue() {
+ if (this.activeCount >= this.concurrency || this.queue.length === 0) {
+ return;
+ }
+
+ this.activeCount++;
+ const { url, resolve, reject } = this.queue.shift();
+
+ this._fetchByHead(url)
+ .then(size => {
+ if (size !== null) this.cache.set(url, size);
+ resolve(size);
+ })
+ .catch(err => {
+ console.warn(`Fetch size failed for ${url}`, err);
+ resolve(null);
+ })
+ .finally(() => {
+ this.activeCount--;
+ this._processQueue();
+ });
+ }
+
+ _fetchByHead(url) {
+ return new Promise((resolve, reject) => {
+ this.gmXhr({
+ method: "HEAD",
+ url: url,
+ timeout: this.timeout,
+ onload: (response) => {
+ const lenStr = response.responseHeaders.match(/content-length:\s*(\d+)/i);
+ if (lenStr && lenStr[1]) {
+ resolve(parseInt(lenStr[1], 10));
+ } else {
+ resolve(null);
+ }
+ },
+ onerror: (err) => reject(err),
+ ontimeout: () => reject(new Error("Timeout"))
+ });
+ });
+ }
+ }
+
+ function formatBytes(bytes) {
+ if (bytes === null || typeof bytes === "undefined" || isNaN(bytes) || bytes < 0) return "";
+ const units = ["B", "KB", "MB", "GB", "TB"];
+ let size = bytes;
+ let unitIndex = 0;
+ while (size >= 1024 && unitIndex < units.length - 1) {
+ size /= 1024;
+ unitIndex++;
+ }
+ const precision = size >= 100 ? 0 : (size >= 10 ? 1 : 2);
+ const value = size.toFixed(precision).replace(/\.0+$|(\.[0-9]*[1-9])0+$/, "$1");
+ return value + " " + units[unitIndex];
+ }
+
+ function updateGalleryHeaderSize(gallery, img, strategy) {
+ if (!gallery || !gallery.eleMaps || !gallery.eleMaps['head-left-img-info-size']) return;
+ const sizeSpan = gallery.eleMaps['head-left-img-info-size'];
+ sizeSpan.textContent = "";
+ sizeSpan.title = "";
+ if (!img || img.nodeName !== 'IMG') return;
+ const sizeUrl = img.src;
+ if (!sizeUrl) return;
+ imageSizeFetcher.getSize(sizeUrl, { strategy: strategy || 'auto' }).then(size => {
+ if (size === null) return;
+ if (gallery.img !== img || img.src !== sizeUrl) return;
+ if (img.naturalWidth && img.naturalHeight) {
+ gallery.eleMaps['head-left-img-info-resolution'].textContent = img.naturalWidth + " x " + img.naturalHeight;
+ }
+ const sizeText = formatBytes(size);
+ sizeSpan.textContent = "(" + sizeText + ")";
+ sizeSpan.title = sizeText;
+ });
+ }
+
+ function updateViewmoreSizeLabel(labelNode, baseText, url, strategy, baseTextGetter) {
+ if (!labelNode || !url) return;
+ const initText = typeof baseTextGetter === "function" ? baseTextGetter() : baseText;
+ labelNode.textContent = initText;
+ imageSizeFetcher.getSize(url, { strategy: strategy || 'local-only' }).then(size => {
+ if (size === null) return;
+ const sizeText = formatBytes(size);
+ const currentBase = typeof baseTextGetter === "function" ? baseTextGetter() : baseText;
+ labelNode.textContent = currentBase + " | " + sizeText;
+ });
+ }
+
+ var viewmoreAutoSizeThrottle = { last: 0 };
+ function scheduleViewmoreAutoSize(labelNode, baseText, url, baseTextGetter) {
+ if (!labelNode || !url) return;
+ var now = Date.now();
+ var delay = Math.max(0, 800 - (now - viewmoreAutoSizeThrottle.last));
+ setTimeout(() => {
+ viewmoreAutoSizeThrottle.last = Date.now();
+ updateViewmoreSizeLabel(labelNode, baseText, url, 'auto', baseTextGetter);
+ }, delay);
+ }
+
+ var imageSizeFetcher = new ImageSizeFetcher(_GM_xmlhttpRequest, { concurrency: 3, timeout: 5000 });
+
var canvas = document.createElement('CANVAS');
if (document.body) {
if (canvas.style) canvas.style.display = "none";
@@ -12100,10 +12272,18 @@ ImgOps | https://imgops.com/#b#`;
3: i18n("urlAndText")
*/
type = parseInt(type || 0);
- if (name) name = name.split("\n")[0].replace(/.*?\/\/[^\/]+\//, "").replace(/\?.*/, "");
- if (!url.replace) url = "";
+ if (name) name = name.split("\n")[0].replace(/.*?\/\/[^\/]+\//, "").replace(/\?.*/, "").replace(/^data:.*/, "");
+ if (!url.replace || url.indexOf("data:") === 0) url = "";
url = url.replace(/.*?\/\/[^\/]+\//, "");
- let nameFromUrl = "";
+ let nameFromUrl = url.match(/.*?([^\/\?\=\&]+)\.\w{2,5}(\?|@|$).*/, "$1");
+ nameFromUrl = nameFromUrl ? nameFromUrl[1] : "";
+ if (/\=&/.test(nameFromUrl)) {
+ nameFromUrl = "";
+ } else {
+ try {
+ nameFromUrl = decodeURIComponent(nameFromUrl);
+ } catch (e) {}
+ }
let ext;
if (_ext && /^\w{2,5}$/.test(_ext)) {
ext = "." + _ext;
@@ -12111,37 +12291,29 @@ ImgOps | https://imgops.com/#b#`;
ext = url.match(/(\.\w{2,5})(\?|@|$)/);
if (ext) {
ext = ext[1];
- nameFromUrl = url.replace(/.*\/([^\/\?]+?)\.\w{2,5}(\?|@|$).*/, "$1");
- if (/\=&/.test(nameFromUrl)) {
- nameFromUrl = "";
- } else {
- try {
- nameFromUrl = decodeURIComponent(nameFromUrl);
- } catch (e) {}
- }
}
}
switch (type) {
case 1:
- name = (name || nameFromUrl || "image").substr(-80);
+ name = (name || nameFromUrl || "image").substr(-200);
break;
case 2:
- name = (nameFromUrl || url || "image").substr(-80);
+ name = (nameFromUrl || url || "image").substr(-200);
break;
case 3:
if (nameFromUrl && !name) {
- name = nameFromUrl.substr(-80);
+ name = nameFromUrl.substr(-200);
} else if (nameFromUrl && name) {
- name = nameFromUrl.substr(-80) + " - " + name.substr(-80);
+ name = nameFromUrl.substr(-200) + " - " + name.substr(-200);
} else if (!nameFromUrl && !name) {
name = "image";
}
break;
default:
- name = (nameFromUrl || name || "image").substr(-80);
+ name = (nameFromUrl || name || "image").substr(-200);
break;
}
- return name.replace(/.*\/([^\/\?]+?)(\?|@|$).*/, "$1").replace(/[\*\/:<>\?\\\|]/g, "").replace(/\.\w{2,5}$/, "").trim() + (ext || ".png");
+ return name.replace(/.*?\/([^\/\?]+?)(\?|@|$).*/, "$1").replace(/[\*\/:<>\?\\\|]/g, "").replace(/\.\w{2,5}$/, "").trim() + (ext || ".png");
}
function canonicalUri(src, href, basePath) {
@@ -12163,6 +12335,7 @@ ImgOps | https://imgops.com/#b#`;
var root_page = /^[^\?#]*\//.exec(url)[0],
root_domain = /^\w+\:\/\/\/?[^\/]+/.exec(root_page)[0],
absolute_regex = /^\w+\:\/\//;
+ src = src.replace(/^\/(\.\.\/)+/, "/");
while (src.indexOf("../") === 0) {
src = src.substr(3);
root_page = root_page.replace(/\/[^\/]+\/$/, "/");
@@ -12179,7 +12352,7 @@ ImgOps | https://imgops.com/#b#`;
urlToBlob(url, (blob, ext) => {
if(blob){
try {
- saveAs(blob, document.title + " - " + getRightSaveName(url, name, type, ext));
+ saveAs(blob, document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " + getRightSaveName(url, name, type, ext));
} catch(e) {
console.log(e);
}
@@ -12187,7 +12360,7 @@ ImgOps | https://imgops.com/#b#`;
});
} : (url, name, type) => {
url = canonicalUri(url);
- name = document.title + " - " + getRightSaveName(url, name, type);
+ name = document.title.replace(/[\*\/:<>\?\\\|]/g, "") + " - " + getRightSaveName(url, name, type);
let urlSplit = ["", ""];
if (url.split) {
urlSplit = url.split("/");
@@ -12225,6 +12398,202 @@ ImgOps | https://imgops.com/#b#`;
};
img.src = dataurl;
}
+ function urlToBlobWithFetch(urlString, cb){
+ fetch(urlString).then(response => response.blob()).then(blob => {
+ let ext = extFromMimeAndUrl(blob.type, urlString);
+ if (blob.type && blob.type.indexOf("text/html") === 0 && (blob.size || 0) < 1000) return cb(null, '');
+ if (ext === "none") ext = "webp";
+ let conversion = formatDict.get(ext);
+ if (canvas && conversion) {
+ var self = this;
+ var a = new FileReader();
+ a.readAsDataURL(blob);
+ a.onload = function (e) {
+ dataURLToCanvas(e.target.result, canvas => {
+ canvas.toBlob(nblob => {
+ if (!nblob) {
+ cb(blob);
+ } else {
+ cb(nblob, conversion || "png");
+ }
+ }, "image/" + (conversion || "png"));
+ });
+ };
+ a.onerror = function (e){
+ cb(blob);
+ }
+ } else {
+ cb(blob, ext);
+ }
+ }).catch(error => {
+ cb(null);
+ });
+ }
+ function loadVideoJsLibrary() {
+ if (!window.videoJsStatus) {
+ window.videoJsStatus = 'none';
+ }
+
+ return new Promise((resolve, reject) => {
+ if (window.videoJsStatus === 'loaded') {
+ return resolve();
+ }
+
+ if (window.videoJsStatus === 'loading') {
+ const interval = setInterval(() => {
+ if (window.videoJsStatus === 'loaded') {
+ clearInterval(interval);
+ resolve();
+ } else if (window.videoJsStatus === 'failed') {
+ clearInterval(interval);
+ reject(new Error('Previous Video.js loading attempt failed.'));
+ }
+ }, 100);
+ return;
+ }
+
+ window.videoJsStatus = 'loading';
+
+ const cssSources = [
+ "https://vjs.zencdn.net/8.23.3/video-js.min.css",
+ "https://unpkg.com/video.js/dist/video-js.min.css",
+ "https://cdn.jsdelivr.net/npm/video.js@8.23.3/dist/video-js.min.css"
+ ];
+ const jsSources = [
+ "https://vjs.zencdn.net/8.23.3/video.min.js",
+ "https://unpkg.com/video.js/dist/video.min.js",
+ "https://cdn.jsdelivr.net/npm/video.js@8.23.3/dist/video.min.js"
+ ];
+ const fetchWithFallback = (urls) => {
+ return new Promise((resolve, reject) => {
+ let lastError = null;
+ const urlsToTry = [...urls];
+
+ const tryNext = () => {
+ if (urlsToTry.length === 0) {
+ reject(new Error(`Failed to load resource after trying all sources. Last error: ${lastError}`));
+ return;
+ }
+
+ const url = urlsToTry.shift();
+ const xhr = new XMLHttpRequest();
+ xhr.open('GET', url);
+ xhr.onload = () => {
+ if (xhr.status === 200) {
+ resolve(xhr.responseText);
+ } else {
+ lastError = `Status ${xhr.status} from ${url}`;
+ console.warn(`Failed to load ${url}, trying next source...`);
+ tryNext();
+ }
+ };
+ xhr.onerror = () => {
+ lastError = `Network error from ${url}`;
+ console.warn(`Failed to load ${url}, trying next source...`);
+ tryNext();
+ };
+ xhr.send();
+ };
+
+ tryNext();
+ });
+ };
+ const pCSS = fetchWithFallback(cssSources).then(cssContent => {
+ const styleElement = document.createElement('style');
+ styleElement.textContent = cssContent;
+ styleElement.id = 'imagus-videojs-styles';
+ document.head.appendChild(styleElement);
+ });
+ const pJS = fetchWithFallback(jsSources).then(jsContent => {
+ Function(jsContent)();
+ });
+
+ Promise.all([pCSS, pJS]).then(() => {
+ window.videoJsStatus = 'loaded';
+ console.timeEnd('Load Video.js');
+ resolve();
+ }).catch(error => {
+ window.videoJsStatus = 'failed';
+ console.error('Failed to load Video.js from all available sources.', error);
+ reject(error);
+ });
+ });
+ }
+ async function initVideojs(media, imgSrc) {
+ await loadVideoJsLibrary();
+ const videoOptions = {
+ autoplay: true
+ };
+ media.className = "video-js vjs-default-skin vjs-fluid";
+ media.width = 1920;
+ media.height = 1080;
+ const player = videojs(media, videoOptions);
+ player.on('loadedmetadata', function() {
+ const vhs = player.tech({ IWillNotUseThisInPlugins: true }).vhs;
+ if (!vhs) {
+ console.warn('VHS engine not found.');
+ return;
+ }
+ const representations = vhs.representations();
+ if (!representations || representations.length === 0) {
+ return;
+ }
+ let highestBandwidth = 0;
+ let highestRepresentation = null;
+ for (let i = 0; i < representations.length; i++) {
+ const representation = representations[i];
+ if (representation.bandwidth > highestBandwidth) {
+ highestBandwidth = representation.bandwidth;
+ highestRepresentation = representation;
+ }
+ }
+ if (highestRepresentation) {
+ representations.forEach(representation => {
+ representation.enabled(representation.id === highestRepresentation.id);
+ });
+ }
+ const originalWidth = highestRepresentation ? highestRepresentation.width : player.videoWidth();
+ const originalHeight = highestRepresentation ? highestRepresentation.height : player.videoHeight();
+ this.addClass('vjs-has-started');
+ media.naturalWidth = originalWidth;
+ media.naturalHeight = originalHeight;
+ media.onload();
+ });
+ player.src({
+ src: imgSrc,
+ fluid: true,
+ type: 'application/x-mpegURL'
+ });
+ }
+ function getCookie(cname) {
+ let name = cname + "=";
+ var ca = document.cookie.split(';');
+ for(let i = 0; i < ca.length; i++) {
+ let c = ca[i];
+ while (c.charAt(0)==' ') c = c.substring(1);
+ if (c.indexOf(name) == 0)
+ return c.substring(name.length,c.length);
+ }
+ return "";
+ }
+ var cookie;
+ function extFromMimeAndUrl(mimeType, url) {
+ let ext = '';
+ if (mimeType) {
+ const cleanMime = mimeType.split(';')[0].trim().toLowerCase();
+ if (cleanMime.indexOf('image/') === 0) {
+ ext = cleanMime.slice(6);
+ } else if (cleanMime.indexOf('text/html') === 0) {
+ ext = 'text/html';
+ }
+ }
+ if (!ext) {
+ const m = String(url || '').match(/\.([a-z0-9]+)(?:$|[?#])/i);
+ ext = m ? m[1].toLowerCase() : '';
+ }
+ if (ext.indexOf('/') !== -1) ext = '';
+ return ext;
+ }
function urlToBlob(url, cb, forcePng, tryTimes = 0) {
tryTimes++;
if (tryTimes > 3) {
@@ -12240,9 +12609,16 @@ ImgOps | https://imgops.com/#b#`;
referer: location.href,
accept: "*/*"
},
+ cookie: cookie,
onload: function(d) {
let blob = d.response;
- let ext = blob.type.replace(/.*image\/([\w\-]+).*/, "$1");
+ if (!blob.type) return urlToBlob(url, cb, forcePng, tryTimes);
+ let ext = extFromMimeAndUrl(blob.type, url);
+ if (blob.type && blob.type.indexOf("text/html") === 0 && (blob.size || 0) < 100000) {
+ urlToBlobWithFetch(url, cb);
+ return;
+ }
+ if (ext === "none") ext = "webp";
let conversion = formatDict.get(ext);
if (canvas && (conversion || forcePng)) {
var self = this;
@@ -12250,8 +12626,12 @@ ImgOps | https://imgops.com/#b#`;
a.readAsDataURL(blob);
a.onload = function (e) {
dataURLToCanvas(e.target.result, canvas => {
- canvas.toBlob(blob => {
- cb(blob, conversion || "png");
+ canvas.toBlob(nblob => {
+ if (!nblob) {
+ cb(blob, ext || "png");
+ } else {
+ cb(nblob, conversion || "png");
+ }
}, "image/" + (conversion || "png"));
});
};
@@ -12272,36 +12652,244 @@ ImgOps | https://imgops.com/#b#`;
}
});
}
- function downloadImg(url, name, type, errCb) {
- urlToBlob(url, (blob, ext) => {
- if(blob){
- try {
- saveAs(blob, document.title + " - " + getRightSaveName(url, name, type, ext));
- } catch(e) {
- _GM_download(url, name, type);
- if (errCb) errCb();
+ var prefs;
+
+ function parseTrustedTypes(cspString) {
+ const policies = new Set();
+ let allowDuplicates = false;
+ let ttDirectiveFound = false;
+ const ttRegex = /trusted-types\s+([^;]+)/gi;
+ let match;
+
+ while ((match = ttRegex.exec(cspString)) !== null) {
+ ttDirectiveFound = true;
+ match[1].trim().split(/\s+/)
+ .forEach(name => {
+ if (name === "'allow-duplicates'") {
+ allowDuplicates = true;
+ } else if (name !== "'none'") {
+ policies.add(name.replace(/'/g, ''));
}
- }else{
- _GM_download(url, name, type);
- if (errCb) errCb();
+ });
+ }
+ return { names: policies, allowDuplicates: allowDuplicates, ttDirectiveFound: ttDirectiveFound };
+ }
+
+ async function getCspTrustedTypesInfo() {
+ const combinedPolicies = new Set();
+ let combinedAllowDuplicates = false;
+ let combinedTtDirectiveFound = false;
+
+ const meta = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
+ if (meta) {
+ const metaResult = parseTrustedTypes(meta.content);
+ metaResult.names.forEach(name => combinedPolicies.add(name));
+ if (metaResult.allowDuplicates) {
+ combinedAllowDuplicates = true;
}
+ if (metaResult.ttDirectiveFound) {
+ combinedTtDirectiveFound = true;
+ }
+ }
+
+ return new Promise((resolve) => {
+ GM_xmlhttpRequest({
+ method: "HEAD",
+ url: window.location.href,
+ onload: function(response) {
+ const cspHeader = response.responseHeaders.split('\r\n')
+ .filter(h => h.toLowerCase().startsWith('content-security-policy:'))
+ .map(h => h.substring(26).trim())
+ .join('; ');
+
+ const headerResult = parseTrustedTypes(cspHeader);
+ headerResult.names.forEach(name => combinedPolicies.add(name));
+ if (headerResult.allowDuplicates) {
+ combinedAllowDuplicates = true;
+ }
+ if (headerResult.ttDirectiveFound) {
+ combinedTtDirectiveFound = true;
+ }
+
+ resolve({
+ names: combinedPolicies,
+ allowDuplicates: combinedAllowDuplicates,
+ ttDirectiveFound: combinedTtDirectiveFound
+ });
+ },
+ onerror: function(error) {
+ resolve({
+ names: combinedPolicies,
+ allowDuplicates: combinedAllowDuplicates,
+ ttDirectiveFound: combinedTtDirectiveFound
+ });
+ }
+ });
});
}
- var prefs;
- var escapeHTMLPolicy;
- if (unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy) {
- escapeHTMLPolicy=unsafeWindow.trustedTypes.createPolicy('pvcep_default', {
- createHTML: (string, sink) => string,
- createScriptURL: string => string,
- createScript: string => string
- });
+
+ function isTrustedTypesEnforced() {
+ try {
+ document.createElement('div').innerHTML = '';
+ return false;
+ } catch (e) {
+ return true;
+ }
+ }
+
+ async function createPolicy() {
+ if (!(unsafeWindow.trustedTypes && unsafeWindow.trustedTypes.createPolicy && isTrustedTypesEnforced())) {
+ return;
+ }
+
+ const { names: allowedNames, allowDuplicates, ttDirectiveFound } = await getCspTrustedTypesInfo();
+
+ if (ttDirectiveFound && !allowDuplicates) {
+ debug("CSP Trusted Types is enforced without 'allow-duplicates'. " +
+ "Skipping policy creation to avoid conflicts with the page.");
+ return;
+ }
+
+ const MY_POLICY_NAME = 'pvcep_default';
+
+ try {
+ escapeHTMLPolicy = unsafeWindow.trustedTypes.createPolicy(MY_POLICY_NAME, {
+ createHTML: (string, sink) => string,
+ createScriptURL: string => string,
+ createScript: string => string
+ });
+ escapeHTMLCreator = escapeHTMLPolicy.createHTML;
+ return;
+ } catch (e) {
+ }
+ debug("Could not create any trusted types policy.");
}
+ let escapeHTMLPolicy = null;
+ let escapeHTMLCreator = null;
+ let canDirectSetHTML = true;
+ let canPolicySetHTML = true;
+
function getBody(doc){
return doc.body || doc.querySelector('body') || doc;
}
function createHTML(html){
- return escapeHTMLPolicy?escapeHTMLPolicy.createHTML(html):html;
+ const fragment = document.createDocumentFragment();
+ if (html === null || html === undefined || html === '') return fragment;
+ parseHTMLToFragment(String(html), fragment, document);
+ return fragment;
+ }
+ const SVG_NS = 'http://www.w3.org/2000/svg';
+ const VOID_TAGS = {
+ area: true,
+ base: true,
+ br: true,
+ col: true,
+ embed: true,
+ hr: true,
+ img: true,
+ input: true,
+ link: true,
+ meta: true,
+ param: true,
+ source: true,
+ track: true,
+ wbr: true
+ };
+ const RAW_TEXT_TAGS = {
+ script: true,
+ style: true,
+ textarea: true,
+ title: true,
+ xmp: true,
+ plaintext: true,
+ noscript: true
+ };
+ const HTML_ENTITIES = {
+ amp: '&',
+ lt: '<',
+ gt: '>',
+ quot: '"',
+ apos: "'",
+ nbsp: '\u00A0'
+ };
+ function decodeEntities(text){
+ return text.replace(/&(#x?[0-9a-fA-F]+|[a-zA-Z]+);/g, function(_, code){
+ if (code[0] === '#') {
+ const isHex = code[1] === 'x' || code[1] === 'X';
+ const num = parseInt(code.slice(isHex ? 2 : 1), isHex ? 16 : 10);
+ if (!isNaN(num)) {
+ try { return String.fromCodePoint(num); } catch(e) {}
+ }
+ return '&' + code + ';';
+ }
+ const key = code.toLowerCase();
+ return (key in HTML_ENTITIES) ? HTML_ENTITIES[key] : '&' + code + ';';
+ });
+ }
+ function parseHTMLToFragment(html, fragment, doc){
+ const stack = [fragment];
+ const tokenRe = /|]*>|<\/?[a-zA-Z][^>]*>|[^<]+/gi;
+ let match;
+ while ((match = tokenRe.exec(html))) {
+ const token = match[0];
+ if (token[0] !== '<') {
+ const text = decodeEntities(token);
+ if (text) stack[stack.length - 1].appendChild(doc.createTextNode(text));
+ continue;
+ }
+ if (token.indexOf('|]*>|<\/?[a-zA-Z][^>]*>|[^<]+/gi;
+ let match;
+ while ((match = tokenRe.exec(html))) {
+ const token = match[0];
+ if (token[0] !== '<') {
+ const text = decodeEntities(token);
+ if (text) stack[stack.length - 1].appendChild(doc.createTextNode(text));
+ continue;
+ }
+ if (token.indexOf('0){
- if(char_f[x])processChar=char_f[x]+processChar;
+ if (!char_f[x]) break;
+ processChar=char_f[x]+processChar;
+ x++;
}
x=0;
while(badd-->0){
- if(char_b[x])processChar+=char_b[x];
+ if (!char_b[x]) break;
+ processChar+=char_b[x];
+ x++;
}
if(processChar.indexOf(curOther) != -1){
newChar=otherChar;
@@ -944,11 +944,15 @@
var curOther=others[k],fadd=curOther.indexOf(char),badd=curOther.length-1-fadd,x=0;
var processChar=char;
while(fadd-->0){
- if(char_f[x])processChar=char_f[x]+processChar;
+ if (!char_f[x]) break;
+ processChar=char_f[x]+processChar;
+ x++;
}
x=0;
while(badd-->0){
- if(char_b[x])processChar+=char_b[x];
+ if (!char_b[x]) break;
+ processChar+=char_b[x];
+ x++;
}
if(processChar.indexOf(curOther) != -1){
newChar=otherChar;
@@ -1122,6 +1126,17 @@
_unsafeWindow.tc2sc = simplized;
_unsafeWindow.sc2tc = traditionalized;
+ window.addEventListener("message", function(event) {
+ if (event.data && event.data.type === "switchChineseRequest") {
+ const receivedData = event.data.payload;
+ const result = receivedData.target === 'sc' ? simplized(receivedData.str) : traditionalized(receivedData.str);
+ window.postMessage({
+ type: "switchChineseResult",
+ payload: result
+ }, "*");
+ }
+ });
+
var storage = {
supportGM: typeof GM_getValue == 'function' && typeof GM_getValue('a', 'b') != 'undefined',
supportGMPromise: typeof GM != 'undefined' && typeof GM.getValue == 'function' && typeof GM.getValue('a','b') != 'undefined',
@@ -1217,14 +1232,14 @@
curLang = isSimple;
}
curLang=!curLang;
- activeEle.innerHTML=curLang?traditionalized(activeEle.innerHTML):simplized(activeEle.innerHTML);
- activeEle.value=curLang?traditionalized(activeEle.value):simplized(activeEle.value);
+ activeEle.innerHTML=curLang?simplized(activeEle.innerHTML):traditionalized(activeEle.innerHTML);
+ activeEle.value=curLang?simplized(activeEle.value):traditionalized(activeEle.value);
}else if("INPUT"==activeEle.nodeName.toUpperCase()){
if (curInput != activeEle) {
curLang = isSimple;
}
curLang=!curLang;
- activeEle.value=curLang?traditionalized(activeEle.value):simplized(activeEle.value);
+ activeEle.value=curLang?simplized(activeEle.value):traditionalized(activeEle.value);
}else{
var selecter;
if(window.getSelection()){
@@ -1275,19 +1290,23 @@
var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
var observer = new MutationObserver(function(records) {
records.map(function(record) {
+ let target = record.target;
+ let parentNode = target && target.parentNode;
+ while (target) {
+ if (/TEXTAREA/i.test(target.nodeName)) return;
+ if (/INPUT/i.test(target.nodeName) && (target.value === "" || target.type === "text" || target.type === "search" || target.type === "hidden")) {
+ return;
+ }
+ if (target.contentEditable == 'true') return;
+ if (target.nodeName.toUpperCase() == 'BODY') {
+ break;
+ }
+ target = target.parentNode;
+ }
if (record.type === "characterData") {
- let target = record.target;
- let parentNode = target && target.parentNode;
if (!parentNode) {
return;
}
- while (target) {
- if (target.contentEditable == 'true') return;
- if (target.nodeName.toUpperCase() == 'BODY') {
- break;
- }
- target = target.parentNode;
- }
transTask(parentNode);
}
if(record.addedNodes){
@@ -1709,12 +1728,16 @@
storage.setItem('sc2tcCombConfig', sc2tcCombConfig);
} catch (e) {
console.log(e);
+ alert("自訂簡繁用語轉換格式錯誤:" + e);
+ return;
}
try {
illiteracyConfig = customIlliteracyInput.value ? JSON.parse(customIlliteracyInput.value) : "";
storage.setItem('illiteracyConfig', illiteracyConfig);
} catch (e) {
console.log(e);
+ alert("通用字詞轉換格式錯誤:" + e);
+ return;
}
storage.setItem('sc2tcCombTree', "");
storage.setItem('tc2scCombTree', "");
@@ -1884,32 +1907,38 @@
function makeCombTree(key, value) {
let curTree=sc2tcCombTree;
for(let i=0;i=12.0.0"
+ }
+}
+
diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/readme.md b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md
new file mode 100644
index 00000000000..670521a96db
--- /dev/null
+++ b/Switch Traditional Chinese and Simplified Chinese/lib/readme.md
@@ -0,0 +1,1082 @@
+# switch-chinese
+
+[Online Demo](https://tool.hoothin.com/chinese-converter)
+
+[简体中文](#简体中文) | [繁體中文](#繁體中文) | [English](#english)
+
+---
+
+## 简体中文
+
+简繁体中文转换库 - 支持简体中文与繁体中文双向转换,基于词组的智能分词处理「一简多繁」问题
+
+[](https://www.npmjs.com/package/switch-chinese) [](https://www.npmjs.com/package/switch-chinese)
+
+### 特性
+
+- **轻量级**:零依赖,体积小,性能优异
+- **智能转换**:支持基于词组的智能分词和「一简多繁」精准转换
+- **多种数据类型**:支持字符串、数组、对象的转换,自动递归处理嵌套结构
+- **自定义词库**:允许用户自定义简繁转换词汇
+- **缓存机制**:支持字典缓存,避免重复初始化
+- **简繁检测**:自动检测文本是简体中文、繁体中文还是未知类型
+- **术语转换**:内置大陆简体与台湾正体的常用术语转换
+- **无依赖**:纯 JavaScript 实现,无需任何第三方依赖
+
+### 安装
+
+使用 npm 安装:
+
+```bash
+npm install switch-chinese
+```
+
+使用 yarn 安装:
+
+```bash
+yarn add switch-chinese
+```
+
+### 快速开始
+
+#### 基础用法
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const { traditionalized, simplized, detect } = stcasc();
+
+// 简体转繁体
+const tc = traditionalized('简繁转换 繁简切换 香烟 香烟袅袅');
+console.log(tc);
+// 输出: 簡繁轉換 繁簡切換 香菸 香煙裊裊
+
+// 繁体转简体
+const sc = simplized('繁體中文');
+console.log(sc);
+// 输出: 繁体中文
+```
+
+#### 检测中文类型
+
+```javascript
+import stcasc, { ChineseType } from 'switch-chinese';
+
+const { detect } = stcasc();
+
+const type1 = detect('简体中文');
+if (type1 === ChineseType.SIMPLIFIED) {
+ console.log('检测到简体中文');
+}
+
+const type2 = detect('繁體中文');
+if (type2 === ChineseType.TRADITIONAL) {
+ console.log('检测到繁体中文');
+}
+
+const type3 = detect('English');
+if (type3 === ChineseType.UNKNOWN) {
+ console.log('未检测到中文');
+}
+```
+
+ChineseType 枚举值:
+- `ChineseType.SIMPLIFIED` (0): 简体中文
+- `ChineseType.TRADITIONAL` (1): 繁体中文
+- `ChineseType.UNKNOWN` (2): 未知类型
+
+#### 转换数组和对象
+
+库支持转换数组和对象中的所有字符串,非字符串值保持原样:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const { traditionalized, simplized } = stcasc();
+
+// 转换数组
+const arr = ['简体中文', '软件', '网络', 123, true, null];
+const arrTc = traditionalized(arr);
+console.log(arrTc);
+// 输出: ['簡體中文', '軟體', '網路', 123, true, null]
+
+// 转换对象
+const obj = {
+ title: '简体中文标题',
+ description: '这是一个简体中文描述',
+ count: 100,
+ active: true,
+ tags: ['软件', '网络', '服务器']
+};
+const objTc = traditionalized(obj);
+console.log(objTc);
+// 输出: {
+// title: '簡體中文標題',
+// description: '這是一個簡體中文描述',
+// count: 100,
+// active: true,
+// tags: ['軟體', '網路', '伺服器']
+// }
+
+// 转换嵌套结构
+const nested = {
+ user: {
+ name: '简体名称',
+ profile: {
+ bio: '这是简体中文简介',
+ skills: ['软件开发', '网络管理']
+ }
+ },
+ count: 42
+};
+const nestedTc = traditionalized(nested);
+// 所有字符串属性值都会被转换,数字等其他类型保持不变
+```
+
+### 高级用法
+
+#### 使用缓存优化性能
+
+在多次调用时,建议使用缓存机制避免重复生成字典,提升性能:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+// 第一次调用,生成字典
+let converter = stcasc();
+const cache = converter.cache;
+
+// 保存缓存到持久化存储(如 localStorage、文件等)
+localStorage.setItem('stcasc-cache', JSON.stringify(cache));
+
+// 后续调用,直接使用缓存
+const cachedData = JSON.parse(localStorage.getItem('stcasc-cache'));
+converter = stcasc(cachedData);
+
+// 现在可以直接使用,无需重新生成字典
+const result = converter.traditionalized('简体中文');
+```
+
+#### 自定义简繁转换词库
+
+可以根据业务需求自定义简繁转换规则:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const customDict = {
+ '身份': '身分',
+ '转义': '跳脫',
+ '转换': '轉檔',
+ '软件': '軟體',
+ '硬件': '硬體',
+ '网络': '網路',
+ '服务器': '伺服器'
+};
+
+const { traditionalized, simplized } = stcasc({}, customDict);
+
+console.log(traditionalized('软件转换'));
+// 输出: 軟體轉檔(使用自定义词库)
+```
+
+#### 禁用术语转换
+
+默认情况下,库会转换一些特定术语(如「知识产权」→「智慧財產權」)。如需禁用此功能:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+// 第三个参数设置为 true 以禁用术语转换
+const { traditionalized } = stcasc({}, {}, true);
+
+console.log(traditionalized('知识产权'));
+// 输出: 知識産權(仅做字符转换,不转换术语)
+```
+
+#### 输出格式选项
+
+库支持多种输出格式:
+
+```javascript
+import stcasc, { OutputFormat } from 'switch-chinese';
+
+const { traditionalized } = stcasc();
+
+// 普通格式(默认)
+const normal = traditionalized('简体中文');
+// 输出: 簡體中文
+
+// 括号格式:同时显示原文和转换后的文本
+const bracket = traditionalized('简体中文', { format: OutputFormat.BRACKET });
+// 输出: 簡(简)體(体)中文
+
+// Ruby 注音格式:适用于 HTML 显示
+const ruby = traditionalized('简体中文', { format: OutputFormat.RUBY });
+// 输出: 簡简 體体 中文
+```
+
+OutputFormat 枚举值:
+- `OutputFormat.NORMAL` (0): 只输出转换后的结果(默认)
+- `OutputFormat.BRACKET` (1): 输出「转换(原文)」格式
+- `OutputFormat.RUBY` (2): 输出 `` HTML 标签格式
+
+### API 文档
+
+#### stcasc(cache?, custom?, disableTerms?)
+
+主函数,用于创建转换器实例。
+
+**参数:**
+
+- `cache` (Object, 可选): 缓存对象,用于避免重复生成字典
+- `custom` (Object, 可选): 自定义简繁转换词库
+- `disableTerms` (Boolean, 可选): 是否禁用术语转换,默认 `false`
+
+**返回值:**
+
+返回包含以下方法的对象:
+
+- `traditionalized(input, options?)`: 将简体中文转换为繁体中文
+ - `input`: 可以是字符串、数组或对象
+ - 字符串:直接转换返回新字符串
+ - 数组:转换所有字符串元素,其他类型保持不变
+ - 对象:递归转换所有字符串属性值,其他类型保持不变
+- `simplized(input, options?)`: 将繁体中文转换为简体中文
+ - `input`: 可以是字符串、数组或对象
+ - 支持的数据类型同 `traditionalized`
+- `detect(text)`: 检测文本的中文类型,返回 ChineseType 枚举值
+- `cache`: 字典缓存对象
+
+**Options 参数:**
+
+- `format` (Number, 可选): 输出格式,使用 `OutputFormat` 常量
+
+#### ChineseType
+
+导出的常量对象,用于表示中文类型检测结果:
+
+```javascript
+export const ChineseType = {
+ SIMPLIFIED: 0, // 简体中文
+ TRADITIONAL: 1, // 繁体中文
+ UNKNOWN: 2 // 未知类型
+};
+```
+
+#### OutputFormat
+
+导出的常量对象,用于表示输出格式选项:
+
+```javascript
+export const OutputFormat = {
+ NORMAL: 0, // 只输出转换后的结果
+ BRACKET: 1, // 输出「转换(原文)」格式
+ RUBY: 2 // 输出 HTML 标签格式
+};
+```
+
+### 转换示例
+
+#### 智能词组转换
+
+该库支持基于上下文的智能词组转换,能够正确处理「一简多繁」的情况:
+
+```javascript
+const { traditionalized } = stcasc();
+
+// 智能识别词组边界
+console.log(traditionalized('香烟袅袅'));
+// 输出: 香煙裊裊
+
+console.log(traditionalized('里长面子'));
+// 输出: 里長面子(「里长」是职务名称)
+
+console.log(traditionalized('吃干面'));
+// 输出: 吃乾麵(「干面」是食物)
+
+console.log(traditionalized('把考卷发回来'));
+// 输出: 把考卷發回來(「发」是动词)
+
+console.log(traditionalized('卷发'));
+// 输出: 捲髮(「卷发」是发型)
+```
+
+#### 术语转换
+
+内置常用的大陆简体与台湾正体术语转换:
+
+```javascript
+const { traditionalized } = stcasc();
+
+console.log(traditionalized('知识产权'));
+// 输出: 智慧財產權
+
+console.log(traditionalized('计算机软件'));
+// 输出: 計算機軟體
+
+console.log(traditionalized('网络服务器'));
+// 输出: 網路伺服器
+```
+
+### 技术特点
+
+#### 高性能
+
+- 使用字典树(Trie)优化词组匹配
+- 支持缓存机制,避免重复初始化
+- 纯 JavaScript 实现,执行效率高
+
+#### 准确转换
+
+- 内置大量简繁对照字符
+- 支持「一简多繁」智能识别
+- 基于词组的上下文分析
+
+#### 易于集成
+
+- ES Module 标准导出
+- TypeScript 类型支持(通过常量枚举)
+- 零依赖,兼容性好
+
+### 浏览器支持
+
+支持所有现代浏览器及 Node.js 环境:
+
+- Chrome
+- Firefox
+- Safari
+- Edge
+- Node.js 12+
+
+### 开源协议
+
+MIT License
+
+### 相关链接
+
+- [GitHub 仓库](https://github.com/hoothin/UserScripts/tree/master/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/lib)
+- [NPM 包地址](https://www.npmjs.com/package/switch-chinese)
+- [问题反馈](https://github.com/hoothin/UserScripts/issues)
+
+### 关键词
+
+简繁转换, 繁简转换, 简体中文, 繁体中文, 正体中文, 中文转换, 一简多繁, 简繁切换, 繁简切换, 中文检测, 智能分词, 自定义词库, 零依赖, 轻量级
+
+---
+
+## English
+
+Lightweight Chinese converter library for bidirectional conversion between Simplified and Traditional Chinese with intelligent word segmentation and one-to-many character mapping support.
+
+[](https://www.npmjs.com/package/switch-chinese) [](https://www.npmjs.com/package/switch-chinese)
+
+### Features
+
+- **Lightweight**: Zero dependencies, small footprint, excellent performance
+- **Intelligent Conversion**: Context-aware word segmentation and accurate one-to-many character mapping
+- **Multiple Data Types**: Supports string, array, and object conversion with automatic recursive processing
+- **Custom Dictionary**: User-defined conversion rules support
+- **Caching Mechanism**: Dictionary caching to avoid repeated initialization
+- **Text Detection**: Automatic detection of Simplified Chinese, Traditional Chinese, or unknown text
+- **Term Conversion**: Built-in mainland China and Taiwan terminology mapping
+- **Zero Dependencies**: Pure JavaScript implementation, no third-party dependencies required
+
+### Installation
+
+Install via npm:
+
+```bash
+npm install switch-chinese
+```
+
+Install via yarn:
+
+```bash
+yarn add switch-chinese
+```
+
+### Quick Start
+
+#### Basic Usage
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const { traditionalized, simplized, detect } = stcasc();
+
+// Simplified to Traditional
+const tc = traditionalized('简繁转换 繁简切换 香烟 香烟袅袅');
+console.log(tc);
+// Output: 簡繁轉換 繁簡切換 香菸 香煙裊裊
+
+// Traditional to Simplified
+const sc = simplized('繁體中文');
+console.log(sc);
+// Output: 繁体中文
+```
+
+#### Text Detection
+
+```javascript
+import stcasc, { ChineseType } from 'switch-chinese';
+
+const { detect } = stcasc();
+
+const type1 = detect('简体中文');
+if (type1 === ChineseType.SIMPLIFIED) {
+ console.log('Detected Simplified Chinese');
+}
+
+const type2 = detect('繁體中文');
+if (type2 === ChineseType.TRADITIONAL) {
+ console.log('Detected Traditional Chinese');
+}
+
+const type3 = detect('English');
+if (type3 === ChineseType.UNKNOWN) {
+ console.log('No Chinese text detected');
+}
+```
+
+ChineseType enumeration values:
+- `ChineseType.SIMPLIFIED` (0): Simplified Chinese
+- `ChineseType.TRADITIONAL` (1): Traditional Chinese
+- `ChineseType.UNKNOWN` (2): Unknown type
+
+#### Converting Arrays and Objects
+
+The library supports converting all strings in arrays and objects, while preserving non-string values:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const { traditionalized, simplized } = stcasc();
+
+// Convert array
+const arr = ['简体中文', '软件', '网络', 123, true, null];
+const arrTc = traditionalized(arr);
+console.log(arrTc);
+// Output: ['簡體中文', '軟體', '網路', 123, true, null]
+
+// Convert object
+const obj = {
+ title: '简体中文标题',
+ description: '这是一个简体中文描述',
+ count: 100,
+ active: true,
+ tags: ['软件', '网络', '服务器']
+};
+const objTc = traditionalized(obj);
+console.log(objTc);
+// Output: {
+// title: '簡體中文標題',
+// description: '這是一個簡體中文描述',
+// count: 100,
+// active: true,
+// tags: ['軟體', '網路', '伺服器']
+// }
+
+// Convert nested structures
+const nested = {
+ user: {
+ name: '简体名称',
+ profile: {
+ bio: '这是简体中文简介',
+ skills: ['软件开发', '网络管理']
+ }
+ },
+ count: 42
+};
+const nestedTc = traditionalized(nested);
+// All string property values will be converted, other types remain unchanged
+```
+
+### Advanced Usage
+
+#### Performance Optimization with Caching
+
+For multiple conversions, use caching mechanism to improve performance:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+// First call, generate dictionary
+let converter = stcasc();
+const cache = converter.cache;
+
+// Save cache to persistent storage (e.g., localStorage, file system)
+localStorage.setItem('stcasc-cache', JSON.stringify(cache));
+
+// Subsequent calls, use cached data
+const cachedData = JSON.parse(localStorage.getItem('stcasc-cache'));
+converter = stcasc(cachedData);
+
+// Now you can use it directly without regenerating dictionary
+const result = converter.traditionalized('简体中文');
+```
+
+#### Custom Conversion Dictionary
+
+Customize conversion rules according to your needs:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const customDict = {
+ '身份': '身分',
+ '转义': '跳脫',
+ '转换': '轉檔',
+ '软件': '軟體',
+ '硬件': '硬體',
+ '网络': '網路',
+ '服务器': '伺服器'
+};
+
+const { traditionalized, simplized } = stcasc({}, customDict);
+
+console.log(traditionalized('软件转换'));
+// Output: 軟體轉檔 (using custom dictionary)
+```
+
+#### Disable Term Conversion
+
+By default, the library converts specific terms (e.g., "知识产权" → "智慧財產權"). To disable this feature:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+// Set the third parameter to true to disable term conversion
+const { traditionalized } = stcasc({}, {}, true);
+
+console.log(traditionalized('知识产权'));
+// Output: 知識産權 (character conversion only, no term conversion)
+```
+
+#### Output Formats
+
+The library supports multiple output formats:
+
+```javascript
+import stcasc, { OutputFormat } from 'switch-chinese';
+
+const { traditionalized } = stcasc();
+
+// Normal format (default)
+const normal = traditionalized('简体中文');
+// Output: 簡體中文
+
+// Bracket format: shows both original and converted text
+const bracket = traditionalized('简体中文', { format: OutputFormat.BRACKET });
+// Output: 簡(简)體(体)中文
+
+// Ruby annotation format: for HTML display
+const ruby = traditionalized('简体中文', { format: OutputFormat.RUBY });
+// Output: 簡简 體体 中文
+```
+
+OutputFormat enumeration values:
+- `OutputFormat.NORMAL` (0): Output converted result only (default)
+- `OutputFormat.BRACKET` (1): Output in "converted(original)" format
+- `OutputFormat.RUBY` (2): Output in `` HTML tag format
+
+### API Reference
+
+#### stcasc(cache?, custom?, disableTerms?)
+
+Main function to create a converter instance.
+
+**Parameters:**
+
+- `cache` (Object, optional): Cache object to avoid regenerating dictionary
+- `custom` (Object, optional): Custom Simplified-Traditional conversion dictionary
+- `disableTerms` (Boolean, optional): Whether to disable term conversion, default `false`
+
+**Returns:**
+
+An object containing the following methods:
+
+- `traditionalized(input, options?)`: Convert Simplified Chinese to Traditional Chinese
+ - `input`: Can be a string, array, or object
+ - String: Directly converts and returns a new string
+ - Array: Converts all string elements, other types remain unchanged
+ - Object: Recursively converts all string property values, other types remain unchanged
+- `simplized(input, options?)`: Convert Traditional Chinese to Simplified Chinese
+ - `input`: Can be a string, array, or object
+ - Supports the same data types as `traditionalized`
+- `detect(text)`: Detect Chinese text type, returns ChineseType enumeration value
+- `cache`: Dictionary cache object
+
+**Options parameter:**
+
+- `format` (Number, optional): Output format, use `OutputFormat` constants
+
+#### ChineseType
+
+Exported constant object representing text detection results:
+
+```javascript
+export const ChineseType = {
+ SIMPLIFIED: 0, // Simplified Chinese
+ TRADITIONAL: 1, // Traditional Chinese
+ UNKNOWN: 2 // Unknown type
+};
+```
+
+#### OutputFormat
+
+Exported constant object representing output format options:
+
+```javascript
+export const OutputFormat = {
+ NORMAL: 0, // Output converted result only
+ BRACKET: 1, // Output "converted(original)" format
+ RUBY: 2 // Output HTML tag format
+};
+```
+
+### Conversion Examples
+
+#### Intelligent Word Segmentation
+
+The library supports context-aware intelligent word segmentation, accurately handling one-to-many character mappings:
+
+```javascript
+const { traditionalized } = stcasc();
+
+// Intelligent phrase boundary recognition
+console.log(traditionalized('香烟袅袅'));
+// Output: 香煙裊裊
+
+console.log(traditionalized('里长面子'));
+// Output: 里長面子 ("里长" is a position title)
+
+console.log(traditionalized('吃干面'));
+// Output: 吃乾麵 ("干面" is a food)
+
+console.log(traditionalized('把考卷发回来'));
+// Output: 把考卷發回來 ("发" is a verb in this context)
+
+console.log(traditionalized('卷发'));
+// Output: 捲髮 ("卷发" is a hairstyle)
+```
+
+#### Term Conversion
+
+Built-in conversion for common mainland China and Taiwan terminology:
+
+```javascript
+const { traditionalized } = stcasc();
+
+console.log(traditionalized('知识产权'));
+// Output: 智慧財產權
+
+console.log(traditionalized('计算机软件'));
+// Output: 計算機軟體
+
+console.log(traditionalized('网络服务器'));
+// Output: 網路伺服器
+```
+
+### Technical Highlights
+
+#### High Performance
+
+- Dictionary tree (Trie) optimization for phrase matching
+- Caching mechanism support to avoid repeated initialization
+- Pure JavaScript implementation for high execution efficiency
+
+#### Accurate Conversion
+
+- Extensive built-in Simplified-Traditional character mappings
+- Intelligent recognition for one-to-many character conversions
+- Context-based phrase analysis
+
+#### Easy Integration
+
+- ES Module standard export
+- TypeScript support through constant enumerations
+- Zero dependencies, excellent compatibility
+
+### Browser Support
+
+Supports all modern browsers and Node.js environments:
+
+- Chrome
+- Firefox
+- Safari
+- Edge
+- Node.js 12+
+
+### License
+
+MIT License
+
+### Links
+
+- [GitHub Repository](https://github.com/hoothin/UserScripts/tree/master/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/lib)
+- [NPM Package](https://www.npmjs.com/package/switch-chinese)
+- [Issue Tracker](https://github.com/hoothin/UserScripts/issues)
+
+### Keywords
+
+Chinese Converter, Simplified Chinese, Traditional Chinese, Chinese Translation, Character Detection, Text Converter, Language Converter, i18n, Localization, Ruby Annotation, One-to-Many Mapping, Intelligent Word Segmentation, Custom Dictionary, Zero Dependencies, Lightweight
+
+---
+
+## 繁體中文
+
+簡繁體中文智能轉換庫 - 支援簡體中文與正體中文雙向轉換,基於詞組的智能分詞處理「一簡多繁」問題
+
+[](https://www.npmjs.com/package/switch-chinese) [](https://www.npmjs.com/package/switch-chinese)
+
+### 特色
+
+- **輕量級**:零依賴,體積小,效能優異
+- **智能轉換**:支援基於詞組的智能分詞和「一簡多繁」精準轉換
+- **多種資料類型**:支援字串、陣列、物件的轉換,自動遞迴處理巢狀結構
+- **自訂詞庫**:允許使用者自訂簡繁轉換詞彙
+- **快取機制**:支援字典快取,避免重複初始化
+- **簡繁檢測**:自動檢測文字是簡體中文、繁體中文還是未知類型
+- **術語轉換**:內建大陸簡體與台灣正體的常用術語轉換
+- **無依賴**:純 JavaScript 實現,無需任何第三方依賴
+
+### 安裝
+
+使用 npm 安裝:
+
+```bash
+npm install switch-chinese
+```
+
+使用 yarn 安裝:
+
+```bash
+yarn add switch-chinese
+```
+
+### 快速開始
+
+#### 基礎用法
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const { traditionalized, simplized, detect } = stcasc();
+
+// 簡體轉繁體
+const tc = traditionalized('简繁转换 繁简切换 香烟 香烟袅袅');
+console.log(tc);
+// 輸出: 簡繁轉換 繁簡切換 香菸 香煙裊裊
+
+// 繁體轉簡體
+const sc = simplized('繁體中文');
+console.log(sc);
+// 輸出: 繁体中文
+```
+
+#### 檢測中文類型
+
+```javascript
+import stcasc, { ChineseType } from 'switch-chinese';
+
+const { detect } = stcasc();
+
+const type1 = detect('简体中文');
+if (type1 === ChineseType.SIMPLIFIED) {
+ console.log('檢測到簡體中文');
+}
+
+const type2 = detect('繁體中文');
+if (type2 === ChineseType.TRADITIONAL) {
+ console.log('檢測到繁體中文');
+}
+
+const type3 = detect('English');
+if (type3 === ChineseType.UNKNOWN) {
+ console.log('未檢測到中文');
+}
+```
+
+ChineseType 列舉值:
+- `ChineseType.SIMPLIFIED` (0): 簡體中文
+- `ChineseType.TRADITIONAL` (1): 繁體中文
+- `ChineseType.UNKNOWN` (2): 未知類型
+
+#### 轉換陣列和物件
+
+函式庫支援轉換陣列和物件中的所有字串,非字串值保持原樣:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const { traditionalized, simplized } = stcasc();
+
+// 轉換陣列
+const arr = ['简体中文', '软件', '网络', 123, true, null];
+const arrTc = traditionalized(arr);
+console.log(arrTc);
+// 輸出: ['簡體中文', '軟體', '網路', 123, true, null]
+
+// 轉換物件
+const obj = {
+ title: '简体中文标题',
+ description: '这是一个简体中文描述',
+ count: 100,
+ active: true,
+ tags: ['软件', '网络', '服务器']
+};
+const objTc = traditionalized(obj);
+console.log(objTc);
+// 輸出: {
+// title: '簡體中文標題',
+// description: '這是一個簡體中文描述',
+// count: 100,
+// active: true,
+// tags: ['軟體', '網路', '伺服器']
+// }
+
+// 轉換巢狀結構
+const nested = {
+ user: {
+ name: '简体名称',
+ profile: {
+ bio: '这是简体中文简介',
+ skills: ['软件开发', '网络管理']
+ }
+ },
+ count: 42
+};
+const nestedTc = traditionalized(nested);
+// 所有字串屬性值都會被轉換,數字等其他類型保持不變
+```
+
+### 進階用法
+
+#### 使用快取最佳化效能
+
+在多次呼叫時,建議使用快取機制避免重複生成字典,提升效能:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+// 第一次呼叫,生成字典
+let converter = stcasc();
+const cache = converter.cache;
+
+// 將快取儲存至持久化儲存(如 localStorage、檔案等)
+localStorage.setItem('stcasc-cache', JSON.stringify(cache));
+
+// 後續呼叫,直接使用快取
+const cachedData = JSON.parse(localStorage.getItem('stcasc-cache'));
+converter = stcasc(cachedData);
+
+// 現在可以直接使用,無需重新生成字典
+const result = converter.traditionalized('简体中文');
+```
+
+#### 自訂簡繁轉換詞庫
+
+可以根據業務需求自訂簡繁轉換規則:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+const customDict = {
+ '身份': '身分',
+ '转义': '跳脫',
+ '转换': '轉檔',
+ '软件': '軟體',
+ '硬件': '硬體',
+ '网络': '網路',
+ '服务器': '伺服器'
+};
+
+const { traditionalized, simplized } = stcasc({}, customDict);
+
+console.log(traditionalized('软件转换'));
+// 輸出: 軟體轉檔(使用自訂詞庫)
+```
+
+#### 停用術語轉換
+
+預設情況下,函式庫會轉換一些特定術語(如「知识产权」→「智慧財產權」)。如需停用此功能:
+
+```javascript
+import stcasc from 'switch-chinese';
+
+// 第三個參數設定為 true 以停用術語轉換
+const { traditionalized } = stcasc({}, {}, true);
+
+console.log(traditionalized('知识产权'));
+// 輸出: 知識産權(僅做字元轉換,不轉換術語)
+```
+
+#### 輸出格式選項
+
+函式庫支援多種輸出格式:
+
+```javascript
+import stcasc, { OutputFormat } from 'switch-chinese';
+
+const { traditionalized } = stcasc();
+
+// 普通格式(預設)
+const normal = traditionalized('简体中文');
+// 輸出: 簡體中文
+
+// 括號格式:同時顯示原文和轉換後的文字
+const bracket = traditionalized('简体中文', { format: OutputFormat.BRACKET });
+// 輸出: 簡(简)體(体)中文
+
+// Ruby 注音格式:適用於 HTML 顯示
+const ruby = traditionalized('简体中文', { format: OutputFormat.RUBY });
+// 輸出: 簡简 體体 中文
+```
+
+OutputFormat 列舉值:
+- `OutputFormat.NORMAL` (0): 只輸出轉換後的結果(預設)
+- `OutputFormat.BRACKET` (1): 輸出「轉換(原文)」格式
+- `OutputFormat.RUBY` (2): 輸出 `` HTML 標籤格式
+
+### API 文件
+
+#### stcasc(cache?, custom?, disableTerms?)
+
+主函式,用於建立轉換器實例。
+
+**參數:**
+
+- `cache` (Object, 可選): 快取物件,用於避免重複生成字典
+- `custom` (Object, 可選): 自訂簡繁轉換詞庫
+- `disableTerms` (Boolean, 可選): 是否停用術語轉換,預設 `false`
+
+**回傳值:**
+
+回傳包含以下方法的物件:
+
+- `traditionalized(input, options?)`: 將簡體中文轉換為繁體中文
+ - `input`: 可以是字串、陣列或物件
+ - 字串:直接轉換並回傳新字串
+ - 陣列:轉換所有字串元素,其他類型保持不變
+ - 物件:遞迴轉換所有字串屬性值,其他類型保持不變
+- `simplized(input, options?)`: 將繁體中文轉換為簡體中文
+ - `input`: 可以是字串、陣列或物件
+ - 支援的資料類型同 `traditionalized`
+- `detect(text)`: 檢測文字的中文類型,回傳 ChineseType 列舉值
+- `cache`: 字典快取物件
+
+**Options 參數:**
+
+- `format` (Number, 可選): 輸出格式,使用 `OutputFormat` 常數
+
+#### ChineseType
+
+匯出的常數物件,用於表示中文類型檢測結果:
+
+```javascript
+export const ChineseType = {
+ SIMPLIFIED: 0, // 簡體中文
+ TRADITIONAL: 1, // 繁體中文
+ UNKNOWN: 2 // 未知類型
+};
+```
+
+#### OutputFormat
+
+匯出的常數物件,用於表示輸出格式選項:
+
+```javascript
+export const OutputFormat = {
+ NORMAL: 0, // 只輸出轉換後的結果
+ BRACKET: 1, // 輸出「轉換(原文)」格式
+ RUBY: 2 // 輸出 HTML 標籤格式
+};
+```
+
+### 轉換範例
+
+#### 智能詞組轉換
+
+本函式庫支援基於上下文的智能詞組轉換,能夠正確處理「一簡多繁」的情況:
+
+```javascript
+const { traditionalized } = stcasc();
+
+// 智能識別詞組邊界
+console.log(traditionalized('香烟袅袅'));
+// 輸出: 香煙裊裊
+
+console.log(traditionalized('里长面子'));
+// 輸出: 里長面子(「里長」是職務名稱)
+
+console.log(traditionalized('吃干面'));
+// 輸出: 吃乾麵(「乾麵」是食物)
+
+console.log(traditionalized('把考卷发回来'));
+// 輸出: 把考卷發回來(「發」是動詞)
+
+console.log(traditionalized('卷发'));
+// 輸出: 捲髮(「捲髮」是髮型)
+```
+
+#### 術語轉換
+
+內建常用的大陸簡體與台灣正體術語轉換:
+
+```javascript
+const { traditionalized } = stcasc();
+
+console.log(traditionalized('知识产权'));
+// 輸出: 智慧財產權
+
+console.log(traditionalized('计算机软件'));
+// 輸出: 計算機軟體
+
+console.log(traditionalized('网络服务器'));
+// 輸出: 網路伺服器
+```
+
+### 技術特點
+
+#### 高效能
+
+- 使用字典樹(Trie)最佳化詞組比對
+- 支援快取機制,避免重複初始化
+- 純 JavaScript 實現,執行效率高
+
+#### 精準轉換
+
+- 內建大量簡繁對照字元
+- 支援「一簡多繁」智能識別
+- 基於詞組的上下文分析
+
+#### 易於整合
+
+- ES Module 標準匯出
+- TypeScript 類型支援(透過常數列舉)
+- 零依賴,相容性佳
+
+### 瀏覽器支援
+
+支援所有現代瀏覽器及 Node.js 環境:
+
+- Chrome
+- Firefox
+- Safari
+- Edge
+- Node.js 12+
+
+### 開源授權
+
+MIT License
+
+### 相關連結
+
+- [GitHub 儲存庫](https://github.com/hoothin/UserScripts/tree/master/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/lib)
+- [NPM 套件位址](https://www.npmjs.com/package/switch-chinese)
+- [問題回報](https://github.com/hoothin/UserScripts/issues)
+
+### 關鍵字
+
+簡繁轉換, 繁簡轉換, 簡體中文, 繁體中文, 正體中文, 中文轉換, 一簡多繁, 簡繁切換, 繁簡切換, 中文檢測, 智能分詞, 自訂詞庫, 零依賴, 輕量級
diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts
new file mode 100644
index 00000000000..350324519b8
--- /dev/null
+++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.d.ts
@@ -0,0 +1,167 @@
+/**
+ * Chinese character type enumeration
+ */
+export declare const ChineseType: {
+ /** Simplified Chinese */
+ readonly SIMPLIFIED: 0;
+ /** Traditional Chinese */
+ readonly TRADITIONAL: 1;
+ /** Unknown type */
+ readonly UNKNOWN: 2;
+};
+
+/**
+ * Output format enumeration
+ */
+export declare const OutputFormat: {
+ /** Normal output - only the converted result */
+ readonly NORMAL: 0;
+ /** Bracket format - outputs「Simplified(Traditional)」or「Traditional(Simplified)」*/
+ readonly BRACKET: 1;
+ /** Ruby annotation format - outputs SimplifiedTraditional */
+ readonly RUBY: 2;
+};
+
+/**
+ * Conversion options
+ */
+export interface ConversionOptions {
+ /**
+ * Output format
+ * @default OutputFormat.NORMAL
+ */
+ format?: 0 | 1 | 2;
+}
+
+/**
+ * Tree node for combination dictionary
+ */
+interface CombTreeNode {
+ end?: string;
+ [key: string]: CombTreeNode | string | undefined;
+}
+
+/**
+ * Cache object for storing conversion dictionaries
+ */
+export interface ConversionCache {
+ sc2tcCombTree?: Record;
+ tc2scCombTree?: Record;
+ stDict?: Record;
+ tsDict?: Record;
+}
+
+/**
+ * Custom dictionary mapping
+ * Key: source text (simplified or traditional)
+ * Value: target text (can be string or array of strings for multiple mappings)
+ */
+export type CustomDictionary = Record;
+
+/**
+ * Result object returned by stcasc function
+ */
+export interface StcascConverter {
+ /**
+ * Convert traditional Chinese to simplified Chinese
+ * @param text - String to convert
+ * @param options - Conversion options
+ * @returns Converted simplified Chinese string
+ */
+ simplized(text: string, options?: ConversionOptions): string;
+
+ /**
+ * Convert traditional Chinese to simplified Chinese (array version)
+ * @param data - Array to convert (converts all strings in the array)
+ * @param options - Conversion options
+ * @returns Array with converted strings
+ */
+ simplized(data: T, options?: ConversionOptions): T;
+
+ /**
+ * Convert traditional Chinese to simplified Chinese (object version)
+ * @param data - Object to convert (converts all string property values)
+ * @param options - Conversion options
+ * @returns Object with converted string values
+ */
+ simplized>(data: T, options?: ConversionOptions): T;
+
+ /**
+ * Convert simplified Chinese to traditional Chinese
+ * @param text - String to convert
+ * @param options - Conversion options
+ * @returns Converted traditional Chinese string
+ */
+ traditionalized(text: string, options?: ConversionOptions): string;
+
+ /**
+ * Convert simplified Chinese to traditional Chinese (array version)
+ * @param data - Array to convert (converts all strings in the array)
+ * @param options - Conversion options
+ * @returns Array with converted strings
+ */
+ traditionalized(data: T, options?: ConversionOptions): T;
+
+ /**
+ * Convert simplified Chinese to traditional Chinese (object version)
+ * @param data - Object to convert (converts all string property values)
+ * @param options - Conversion options
+ * @returns Object with converted string values
+ */
+ traditionalized>(data: T, options?: ConversionOptions): T;
+
+ /**
+ * Detect Chinese text type
+ * @param text - Text to detect
+ * @returns ChineseType value (0=SIMPLIFIED, 1=TRADITIONAL, 2=UNKNOWN)
+ */
+ detect(text: string): 0 | 1 | 2;
+
+ /**
+ * Cached conversion dictionaries
+ */
+ cache: ConversionCache;
+}
+
+/**
+ * Initialize Chinese converter with optional cache and custom dictionary
+ *
+ * @param cache - Optional cache object to reuse conversion dictionaries
+ * @param custom - Optional custom dictionary for special term conversions
+ * @param disableTerms - If true, disables built-in term conversions
+ * @returns Converter object with conversion methods
+ *
+ * @example
+ * ```typescript
+ * import stcasc from 'switch-chinese';
+ *
+ * const converter = stcasc();
+ * const traditional = converter.traditionalized('简体中文');
+ * const simplified = converter.simplized('繁體中文');
+ * const type = converter.detect('繁體中文');
+ * ```
+ *
+ * @example
+ * ```typescript
+ * // With custom dictionary
+ * const converter = stcasc({}, {
+ * '自定义词': '自訂詞',
+ * '程序': ['程式', '程序']
+ * });
+ * ```
+ *
+ * @example
+ * ```typescript
+ * // With output format
+ * const converter = stcasc();
+ * const result = converter.traditionalized('简体', { format: 1 });
+ * // Output: 簡體(简体)
+ * ```
+ */
+declare function stcasc(
+ cache?: ConversionCache,
+ custom?: CustomDictionary,
+ disableTerms?: boolean
+): StcascConverter;
+
+export default stcasc;
diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js
new file mode 100644
index 00000000000..2256dc7222a
--- /dev/null
+++ b/Switch Traditional Chinese and Simplified Chinese/lib/stcasc.lib.js
@@ -0,0 +1,988 @@
+'use strict';
+export const ChineseType = {
+ SIMPLIFIED: 0,
+ TRADITIONAL: 1,
+ UNKNOWN: 2
+};
+
+export const OutputFormat = {
+ NORMAL: 0, // 只输出转换后的结果
+ BRACKET: 1, // 输出「简(繁)」或「繁(简)」格式
+ RUBY: 2 // 输出 简繁 格式
+};
+
+const scStr = '万与丑专业丛东丝丢两严丧个丰临为为丽举么么义乌乐乔习乡书买乱争于亏云亘亚产产亩亲亵亸亿仅仆从仑仓仪们价众众优伙会伛伞伟传伡伣伤伥伦伧伪伫体余佣佥侠侣侥侦侧侨侩侪侬侭俣俦俨俩俪俫俭借债倾偬偻偾偿傤傥傧储傩儿克兑兖党兰关兴兹养兽冁内冈册冗写军农冢冯冲冲决况冻净凄准凉凌减凑凛几凤处凫凭凯凶击凿刍划刘则刚创删别刬刭制刹刽刾刿剀剂剐剑剥剧劝办务劢动励劲劳势勋勖勚匀匦匮区医华协单卖卜卢卤卧卫却卷厂厅历历厉压厌厍厐厕厘厠厢厣厦厨厩厮县叁参叆叇双发发变叙叠只台叶号叹叽吁后吓吕吗吨听启吴呆呐呒呓呕呖呗员呙呛呜周咏咙咛咝咤咨咸响哑哒哓哔哕哗哙哜哝哟唇唉唛唝唠唡唢唤啧啬啭啮啯啰啴啸喂喷喽喾嗫嗳嘘嘤嘱噜嚣团园囱围囵国图圆圣圹场坏块坚坛坛坛坛坜坝坞坟坠垄垅垆垒垦垩垫垭垯垱垲垴埘埙埚堑堕塆墙墻壊壮声壳壶壸処备复复够头夸夹夺奁奂奋奖奥奬妆妇妈妩妪妫姗姜姹娄娅娆娇娈娱娲娴婳婴婵婶媪媭嫒嫔嫱嬀嬷孙学孪宁宁宝实宠审宪宫宽宽宾寝对寻导寿将尔尘尝尧尴尸尽尽层屃屉届属屡屦屿岁岂岖岗岘岚岛岩岭岳岽岿峃峄峡峣峤峥峦峰崂崃崄崭嵘嵚嵝巅巨巩巯币布帅师帏帐帘帜带帧帮帱帻帼幂干干并并广庄庆庐庑库应庙庞废庼廏廪开异弃弑张弥弪弯弹强归当录彝彟彦彨彻征径徕御忆忏志忧念忾怀态怂怃怄怅怆怜总怼怿恋恒恳恶恶恸恹恺恻恼恽悦悫悬悭悮悯惊惧惨惩惫惬惭惮惯愠愤愦愿慑慭懑懒懔戆戋戏戗战戬户扎扑托扦执扩扪扫扬扰抚抛抟抠抡抢护报抬抻担拟拢拣拥拦拧拨择挂挚挛挜挝挞挟挠挡挢挣挤挥挦捂捝捞损捡换捣据捻掳掴掷掸掺掼揽揾揿搀搁搂搄搅携摄摅摆摇摈摊撄撑撵撷撸撺擜擞攒敌敍敚敛敩数斋斓斗斩断无旧时旷旸昙昼昽显晋晒晓晔晕晖暂暧札术朴机杀杂权杠条来杨杩杰松板极构枞枢枣枥枧枨枪枫枭柜柠柽栀栅标栈栉栊栋栌栎栏树栖样栾桠桡桢档桤桥桦桧桨桩桪梁梦梼梾梿检棁棂棱椁椝椟椠椢椤椫椭椮楼榄榅榇榈榉榝槚槛槟槠横樯樱橥橱橹橼檐檩欢欤欧歼殁殇残殒殓殚殡殴殻毁毂毕毙毡毵氇气氢氩氲汇汇汉污汤汹沟没沣沤沥沦沧沨沩沪泄泞注泪泶泷泸泺泻泼泽泾洁洒洼浃浅浆浇浈浉浊测浍济浏浐浑浒浓浔浕涂涌涚涛涝涞涟涠涡涢涣涤润涧涨涩淀渊渌渍渎渐渑渔渖渗温游湾湿溁溃溅溆溇滗滚滞滟滠满滢滤滥滦滨滩滪潆潇潋潍潙潜潨潴澛澜濑濒灏灭灯灵灶灾灿炀炉炖炜炝点炼炽烁烂烃烛烟烟烦烧烨烩烫烬热焕焖焘煴爱爷牍牦牵牺犊状犷犸犹狈狝狞独狭狮狯狰狱狲猃猎猕猡猪猫猬献獭玑玙玚玛玮环现玱玺珐珑珰珲琎琏琐琼瑶瑷瑸璎瓒瓮瓯産电画畅畴疖疗疟疠疡疬疭疮疯疱疴痈痉痒痖痨痪痫痴痹瘅瘆瘉瘗瘘瘪瘫瘾瘿癞癣癫皋皑皱皲盏盐监盖盗盘眍眦眬着睁睐睑睾瞆瞒瞩矫矶矾矿砀码砖砗砚砜砺砻砾础硁硅硕硖硗硙硚确硵硷碍碛碜碱礼祃祎祢祯祷祸禀禄禅离秃秆种秘积称秸秽秾稆税稣稳穑穞穷窃窍窎窑窜窝窥窦窭竖竞竪笃笋笔笕笺笼笾筑筚筛筜筝筹筼签签筿简箓箦箧箨箩箪箫篑篓篮篯篱簖籁籴类籼粜粝粤粪粮糁糇糍系系紧绝絷纟纠纡红纣纤纥约级纨纩纪纫纬纭纮纯纰纱纲纳纴纵纶纷纸纹纺纻纼纽纾线绀绁绂练组绅细织终绉绊绋绌绍绎经绐绑绒结绔绕绖绗绘给绚绛络絶绞统绠绡绢绣绤绥绦继绨绩绪绫绬续绮绯绰绱绲绳维绵绶绷绸绹绺绻综绽绾绿缀缁缂缃缄缅缆缇缈缉缊缋缌缍缎缏缑缒缓缔缕编缗缘缙缚缛缜缝缞缟缠缡缢缣缤缥缦缧缨缩缪缫缬缭缮缯缰缱缲缳缴缵罂网罗罚罢罴羁羟羡群翘翙翚翱耢耧耸耻聂聋职聍联聩聪肃肠肤肮肴肾肿胀胁胆胜胧胨胪胫胶脉脍脏脐脑脓脔脚脱脶脸腊腌腘腭腻腼腽腾膑膻臜致舆舍舣舰舱舻艰艳艺节芈芗芜芦苁苇苈苋苌苍苎苏苧苹范茎茏茑茔茕茧荆荐荙荚荛荜荝荞荟荠荡荣荤荥荦荧荨荩荪荫荬荭荮药莅莱莲莳莴莶获莸莹莺莼萚萝萤营萦萧萨葱蒀蒇蒉蒋蒌蒏蓝蓟蓠蓣蓥蓦蔂蔷蔹蔺蔼蕰蕲蕴薮藓蘖虏虑虚虫虬虮虱虽虾虿蚀蚁蚂蚃蚕蚝蚬蛊蛎蛏蛮蛰蛱蛲蛳蛴蜕蜗蜡蝇蝈蝉蝎蝼蝾螀螨蟏衅衆衔补表衬衮袄袅袆袜袭袯装裆裈裢裣裤裥褛褴襕见观觃规觅视觇览觉觊觋觌觍觎觏觐觑觞触觯訚詟誉誊说说谣讠计订讣认讥讦讧讨让讪讫讬训议讯记讱讲讳讴讵讶讷许讹论讻讼讽设访诀证诂诃评诅识诇诈诉诊诋诌词诎诏诐译诒诓诔试诖诗诘诙诚诛诜话诞诟诠诡询诣诤该详诧诨诩诪诫诬语诮误诰诱诲诳诵诶请诸诹诺读诼诽课诿谀谁谂调谄谅谆谇谈谉谊谋谌谍谎谏谐谑谒谓谔谕谖谗谘谙谚谛谜谝谞谟谠谡谢谣谤谥谦谧谨谩谪谫谬谭谮谯谰谱谲谳谴谵谶谷豮贜贝贞负贠贡财责贤败账货质贩贪贫贬购贮贯贰贱贲贳贴贵贶贷贸费贺贻贼贽贾贿赀赁赂赃资赅赆赇赈赉赊赋赌赍赎赏赐赑赒赓赔赕赖赗赘赙赚赛赜赝赞赞赟赠赡赢赣赪赵赶趋趱趸跃跄跖跞跡践跶跷跸跹跻踊踌踪踬踯蹑蹒蹰蹿躏躜躯軆輼车轧轨轩轪轫转轭轮软轰轱轲轳轴轵轶轷轸轹轺轻轼载轾轿辀辁辂较辄辅辆辇辈辉辊辋辌辍辎辏辐辑辒输辔辕辖辗辘辙辚辞辟辩辫边辽达迁过迈运还这进远违连迟迩迳迹适选逊递逦逻遗遥邓邝邬邮邹邺邻郁郏郐郑郓郦郧郸酂酝酦酱酽酾酿采释里里鈎鉴鉴銮鋭録錾钅钆钇针钉钊钋钌钍钎钏钐钑钒钓钔钕钖钗钘钙钚钛钜钝钞钟钟钠钡钢钣钤钥钦钧钨钩钪钫钬钭钮钯钰钱钲钳钴钵钶钷钸钹钺钻钼钽钾钿铀铁铂铃铄铅铆铇铈铉铊铋铌铍铎铏铐铑铒铓铔铕铖铗铘铙铚铛铜铝铞铟铠铡铢铣铤铥铦铧铨铩铪铫铬铭铮铯铰铱铲铳铴铵银铷铸铹铺铻铼铽链链铿销锁锂锃锄锅锆锇锈锈锉锊锋锌锍锎锏锐锑锒锓锔锕锖锗锘错锚锛锜锝锞锟锠锡锢锣锤锥锦锧锨锩锪锫锬锭键锯锰锱锲锳锴锵锶锷锸锹锺锻锼锽锾锿镀镁镂镃镄镅镆镇镈镉镊镋镌镍镎镏镐镑镒镓镔镕镖镗镘镙镚镛镜镝镞镟镠镡镢镣镤镥镦镧镨镩镪镫镬镭镮镯镰镱镲镳镴镵镶长门闩闪闫闬闭问闯闰闱闲闲闳间闵闶闷闸闹闺闻闼闽闾闿阀阁阂阃阄阅阆阇阈阉阊阋阌阍阎阏阐阑阒阓阔阕阖阗阘阙阚阛队阳阴阵阶际陆陇陈陉陕陦陧陨险随隐隶隽难雇雏雠雳雾霁霉霡霭靓靔静面靥鞑鞒鞯鞲韦韧韨韩韪韫韬韵頽页顶顷顸项顺须顼顽顾顿颀颁颂颃预颅领颇颈颉颊颋颌颍颎颏颐频颒颓颔颕颖颗题颙颚颛颜颜额颞颟颠颡颢颣颤颥颦颧风飏飐飑飒飓飔飕飖飗飘飙飚飞飨餍饣饤饥饦饧饨饩饪饫饬饭饮饯饰饱饲饳饴饵饶饷饸饹饺饻饼饽饾饿馀馁馂馃馄馅馆馇馈馉馊馋馌馍馎馏馐馑馒馓馔馕駡马驭驮驯驰驱驲驳驴驵驶驷驸驹驺驻驼驽驾驿骀骁骂骃骄骅骆骇骈骉骊骋验骍骎骏骐骑骒骓骔骕骖骗骘骙骚骛骜骝骞骟骠骡骢骣骤骥骦骧髅髋髌鬓鬶魇魉鱼鱽鱾鱿鲀鲁鲂鲃鲄鲅鲆鲇鲈鲉鲊鲋鲌鲍鲎鲏鲐鲑鲒鲓鲔鲕鲖鲗鲘鲙鲚鲛鲜鲝鲞鲟鲠鲡鲢鲣鲤鲥鲦鲧鲨鲩鲪鲫鲬鲭鲮鲯鲰鲱鲲鲳鲴鲵鲶鲷鲸鲹鲺鲻鲼鲽鲾鲿鳀鳁鳂鳃鳄鳅鳆鳇鳈鳉鳊鳋鳌鳍鳎鳏鳐鳑鳒鳓鳔鳕鳖鳗鳘鳙鳛鳜鳝鳞鳟鳠鳡鳢鳣鳤鷀鷄鸟鸠鸡鸢鸣鸤鸥鸦鸧鸨鸩鸪鸫鸬鸭鸮鸯鸰鸱鸲鸳鸴鸵鸶鸷鸸鸹鸺鸻鸼鸽鸾鸿鹀鹁鹂鹃鹄鹅鹆鹇鹈鹉鹊鹋鹌鹍鹎鹏鹐鹑鹒鹓鹔鹕鹖鹗鹘鹙鹚鹛鹜鹝鹞鹟鹠鹡鹢鹣鹤鹥鹦鹧鹨鹩鹪鹫鹬鹭鹮鹯鹰鹱鹲鹳鹴鹾麦麸麹麽黄黉黡黩黪黾鼋鼌鼍鼹齐齑齿龀龁龂龃龄龅龆龇龈龉龊龋龌龙龚龛龟酸';
+const tcStr = '萬與醜專業叢東絲丟兩嚴喪個豐臨為爲麗舉麽麼義烏樂喬習鄉書買亂爭於虧雲亙亞産產畝親褻嚲億僅僕從侖倉儀們價衆眾優夥會傴傘偉傳俥俔傷倀倫傖僞佇體餘傭僉俠侶僥偵側僑儈儕儂儘俁儔儼倆儷倈儉藉債傾傯僂僨償儎儻儐儲儺兒剋兌兗黨蘭關興茲養獸囅內岡冊宂寫軍農塚馮沖衝決況凍淨淒準涼淩減湊凜幾鳳處鳧憑凱兇擊鑿芻劃劉則剛創刪別剗剄製剎劊㓨劌剴劑剮劍剝劇勸辦務勱動勵勁勞勢勳勗勩勻匭匱區醫華協單賣蔔盧鹵臥衛卻捲廠廳曆歷厲壓厭厙龎廁釐廁廂厴廈廚廄廝縣叄參靉靆雙發髮變敘疊隻臺葉號嘆嘰籲後嚇呂嗎噸聽啟吳獃吶嘸囈嘔嚦唄員咼嗆嗚週詠嚨嚀噝吒諮鹹響啞噠嘵嗶噦嘩噲嚌噥喲脣欸嘜嗊嘮啢嗩喚嘖嗇囀齧嘓囉嘽嘯餵噴嘍嚳囁噯噓嚶囑嚕囂團園囪圍圇國圖圓聖壙場壞塊堅壇罎罈壜壢壩塢墳墜壟壠壚壘墾堊墊埡墶壋塏堖塒壎堝塹墮壪牆牆壞壯聲殼壺壼處備複復夠頭誇夾奪奩奐奮獎奧獎妝婦媽嫵嫗媯姍薑奼婁婭嬈嬌孌娛媧嫻嫿嬰嬋嬸媼嬃嬡嬪嬙媯嬤孫學孿寧甯寶實寵審憲宮寬寛賓寢對尋導壽將爾塵嘗堯尷屍盡儘層屭屜屆屬屢屨嶼歲豈嶇崗峴嵐島巖嶺嶽崬巋嶨嶧峽嶢嶠崢巒峯嶗崍嶮嶄嶸嶔嶁巔鉅鞏巰幣佈帥師幃帳簾幟帶幀幫幬幘幗冪幹乾並併廣莊慶廬廡庫應廟龐廢廎廄廩開異棄弒張彌弳彎彈強歸當錄彜彠彥彲徹徵徑徠禦憶懺誌憂唸愾懷態慫憮慪悵愴憐總懟懌戀恆懇惡噁慟懨愷惻惱惲悅愨懸慳悞憫驚懼慘懲憊愜慚憚慣慍憤憒願懾憖懣懶懍戇戔戲戧戰戩戶紮撲託扡執擴捫掃揚擾撫拋摶摳掄搶護報擡捵擔擬攏揀擁攔擰撥擇掛摯攣掗撾撻挾撓擋撟掙擠揮撏摀挩撈損撿換搗據撚擄摑擲撣摻摜攬搵撳攙擱摟揯攪攜攝攄擺搖擯攤攖撐攆擷擼攛㩵擻攢敵敘敓斂斆數齋斕鬥斬斷無舊時曠暘曇晝曨顯晉曬曉曄暈暉暫曖劄術樸機殺雜權槓條來楊榪傑鬆闆極構樅樞棗櫪梘棖槍楓梟櫃檸檉梔柵標棧櫛櫳棟櫨櫟欄樹棲樣欒椏橈楨檔榿橋樺檜槳樁樳樑夢檮棶槤檢梲櫺稜槨槼櫝槧槶欏樿橢槮樓欖榲櫬櫚櫸樧檟檻檳櫧橫檣櫻櫫櫥櫓櫞簷檁歡歟歐殲歿殤殘殞殮殫殯毆殼毀轂畢斃氈毿氌氣氫氬氳彙匯漢汙湯洶溝沒灃漚瀝淪滄渢溈滬洩濘註淚澩瀧瀘濼瀉潑澤涇潔灑窪浹淺漿澆湞溮濁測澮濟瀏滻渾滸濃潯濜塗湧涗濤澇淶漣潿渦溳渙滌潤澗漲澀澱淵淥漬瀆漸澠漁瀋滲溫遊灣濕濚潰濺漵漊潷滾滯灩灄滿瀅濾濫灤濱灘澦瀠瀟瀲濰溈潛潀瀦瀂瀾瀨瀕灝滅燈靈竈災燦煬爐燉煒熗點煉熾爍爛烴燭煙菸煩燒燁燴燙燼熱煥燜燾熅愛爺牘犛牽犧犢狀獷獁猶狽獮獰獨狹獅獪猙獄猻獫獵獼玀豬貓蝟獻獺璣璵瑒瑪瑋環現瑲璽琺瓏璫琿璡璉瑣瓊瑤璦璸瓔瓚甕甌產電畫暢疇癤療瘧癘瘍癧瘲瘡瘋皰痾癰痙癢瘂癆瘓癇癡痺癉瘮癒瘞瘻癟癱癮癭癩癬癲臯皚皺皸盞鹽監蓋盜盤瞘眥矓著睜睞瞼睪瞶瞞矚矯磯礬礦碭碼磚硨硯碸礪礱礫礎硜矽碩硤磽磑礄確磠鹼礙磧磣堿禮禡禕禰禎禱禍稟祿禪離禿稈種祕積稱稭穢穠穭稅穌穩穡穭窮竊竅窵窯竄窩窺竇窶豎競豎篤筍筆筧箋籠籩築篳篩簹箏籌篔簽籤篠簡籙簀篋籜籮簞簫簣簍籃籛籬籪籟糴類秈糶糲粵糞糧糝餱餈係繫緊絕縶糹糾紆紅紂纖紇約級紈纊紀紉緯紜紘純紕紗綱納紝縱綸紛紙紋紡紵紖紐紓線紺紲紱練組紳細織終縐絆紼絀紹繹經紿綁絨結絝繞絰絎繪給絢絳絡絕絞統綆綃絹繡綌綏縧繼綈績緒綾緓續綺緋綽鞝緄繩維綿綬繃綢綯綹綣綜綻綰綠綴緇緙緗緘緬纜緹緲緝縕繢緦綞緞緶緱縋緩締縷編緡緣縉縛縟縝縫縗縞纏縭縊縑繽縹縵縲纓縮繆繅纈繚繕繒韁繾繰繯繳纘罌網羅罰罷羆羈羥羨羣翹翽翬翺耮耬聳恥聶聾職聹聯聵聰肅腸膚骯餚腎腫脹脅膽勝朧腖臚脛膠脈膾髒臍腦膿臠腳脫腡臉臘醃膕齶膩靦膃騰臏羶臢緻輿捨艤艦艙艫艱豔藝節羋薌蕪蘆蓯葦藶莧萇蒼苧蘇薴蘋範莖蘢蔦塋煢繭荊薦薘莢蕘蓽萴蕎薈薺蕩榮葷滎犖熒蕁藎蓀蔭蕒葒葤藥蒞萊蓮蒔萵薟獲蕕瑩鶯蓴蘀蘿螢營縈蕭薩蔥蒕蕆蕢蔣蔞醟藍薊蘺蕷鎣驀虆薔蘞藺藹薀蘄蘊藪蘚櫱虜慮虛蟲虯蟣蝨雖蝦蠆蝕蟻螞蠁蠶蠔蜆蠱蠣蟶蠻蟄蛺蟯螄蠐蛻蝸蠟蠅蟈蟬蠍螻蠑螿蟎蠨釁眾銜補錶襯袞襖裊褘襪襲襏裝襠褌褳襝褲襉褸襤襴見觀覎規覓視覘覽覺覬覡覿覥覦覯覲覷觴觸觶誾讋譽謄說説謡訁計訂訃認譏訐訌討讓訕訖託訓議訊記訒講諱謳詎訝訥許訛論訩訟諷設訪訣證詁訶評詛識詗詐訴診詆謅詞詘詔詖譯詒誆誄試詿詩詰詼誠誅詵話誕詬詮詭詢詣諍該詳詫諢詡譸誡誣語誚誤誥誘誨誑誦誒請諸諏諾讀諑誹課諉諛誰諗調諂諒諄誶談讅誼謀諶諜謊諫諧謔謁謂諤諭諼讒諮諳諺諦謎諞諝謨讜謖謝謠謗謚謙謐謹謾謫譾謬譚譖譙讕譜譎讞譴譫讖穀豶贓貝貞負貟貢財責賢敗賬貨質販貪貧貶購貯貫貳賤賁貰貼貴貺貸貿費賀貽賊贄賈賄貲賃賂贓資賅贐賕賑賚賒賦賭齎贖賞賜贔賙賡賠賧賴賵贅賻賺賽賾贗贊讚贇贈贍贏贛赬趙趕趨趲躉躍蹌蹠躒蹟踐躂蹺蹕躚躋踴躊蹤躓躑躡蹣躕躥躪躦軀體轀車軋軌軒軑軔轉軛輪軟轟軲軻轤軸軹軼軤軫轢軺輕軾載輊轎輈輇輅較輒輔輛輦輩輝輥輞輬輟輜輳輻輯轀輸轡轅轄輾轆轍轔辭闢辯辮邊遼達遷過邁運還這進遠違連遲邇逕跡適選遜遞邐邏遺遙鄧鄺鄔郵鄒鄴鄰鬱郟鄶鄭鄆酈鄖鄲酇醞醱醬釅釃釀採釋裏裡鉤鑒鑑鑾銳錄鏨釒釓釔針釘釗釙釕釷釺釧釤鈒釩釣鍆釹鍚釵鈃鈣鈈鈦鉅鈍鈔鍾鐘鈉鋇鋼鈑鈐鑰欽鈞鎢鈎鈧鈁鈥鈄鈕鈀鈺錢鉦鉗鈷缽鈳鉕鈽鈸鉞鑽鉬鉭鉀鈿鈾鐵鉑鈴鑠鉛鉚鉋鈰鉉鉈鉍鈮鈹鐸鉶銬銠鉺鋩錏銪鋮鋏鋣鐃銍鐺銅鋁銱銦鎧鍘銖銑鋌銩銛鏵銓鎩鉿銚鉻銘錚銫鉸銥鏟銃鐋銨銀銣鑄鐒鋪鋙錸鋱鏈鍊鏗銷鎖鋰鋥鋤鍋鋯鋨鏽銹銼鋝鋒鋅鋶鐦鐧銳銻鋃鋟鋦錒錆鍺鍩錯錨錛錡鍀錁錕錩錫錮鑼錘錐錦鑕鍁錈鍃錇錟錠鍵鋸錳錙鍥鍈鍇鏘鍶鍔鍤鍬鍾鍛鎪鍠鍰鎄鍍鎂鏤鎡鐨鎇鏌鎮鎛鎘鑷钂鐫鎳鎿鎦鎬鎊鎰鎵鑌鎔鏢鏜鏝鏍鏰鏞鏡鏑鏃鏇鏐鐔钁鐐鏷鑥鐓鑭鐠鑹鏹鐙鑊鐳鐶鐲鐮鐿鑔钀鑞鑱鑲長門閂閃閆閈閉問闖閏闈閑閒閎間閔閌悶閘鬧閨聞闥閩閭闓閥閣閡閫鬮閱閬闍閾閹閶鬩閿閽閻閼闡闌闃闠闊闋闔闐闒闕闞闤隊陽陰陣階際陸隴陳陘陝隯隉隕險隨隱隸雋難僱雛讎靂霧霽黴霢靄靚靝靜麵靨韃鞽韉韝韋韌韍韓韙韞韜韻頹頁頂頃頇項順須頊頑顧頓頎頒頌頏預顱領頗頸頡頰頲頜潁熲頦頤頻頮頹頷頴穎顆題顒顎顓顔顏額顳顢顛顙顥纇顫顬顰顴風颺颭颮颯颶颸颼颻飀飄飆飈飛饗饜飠飣饑飥餳飩餼飪飫飭飯飲餞飾飽飼飿飴餌饒餉餄餎餃餏餅餑餖餓餘餒餕餜餛餡館餷饋餶餿饞饁饃餺餾饈饉饅饊饌饢罵馬馭馱馴馳驅馹駁驢駔駛駟駙駒騶駐駝駑駕驛駘驍罵駰驕驊駱駭駢驫驪騁驗騂駸駿騏騎騍騅騌驌驂騙騭騤騷騖驁騮騫騸驃騾驄驏驟驥驦驤髏髖髕鬢鬹魘魎魚魛魢魷魨魯魴䰾魺鮁鮃鯰鱸鮋鮓鮒鮊鮑鱟鮍鮐鮭鮚鮳鮪鮞鮦鰂鮜鱠鱭鮫鮮鮺鯗鱘鯁鱺鰱鰹鯉鰣鰷鯀鯊鯇鮶鯽鯒鯖鯪鯕鯫鯡鯤鯧鯝鯢鯰鯛鯨鰺鯴鯔鱝鰈鰏鱨鯷鰮鰃鰓鱷鰍鰒鰉鰁鱂鯿鰠鼇鰭鰨鰥鰩鰟鰜鰳鰾鱈鼈鰻鰵鱅鰼鱖鱔鱗鱒鱯鱤鱧鱣䲘鶿雞鳥鳩雞鳶鳴鳲鷗鴉鶬鴇鴆鴣鶇鸕鴨鴞鴦鴒鴟鴝鴛鷽鴕鷥鷙鴯鴰鵂鴴鵃鴿鸞鴻鵐鵓鸝鵑鵠鵝鵒鷳鵜鵡鵲鶓鵪鵾鵯鵬鵮鶉鶊鵷鷫鶘鶡鶚鶻鶖鶿鶥鶩鷊鷂鶲鶹鶺鷁鶼鶴鷖鸚鷓鷚鷯鷦鷲鷸鷺䴉鸇鷹鸌鸏鸛鸘鹺麥麩麴麼黃黌黶黷黲黽黿鼂鼉鼴齊齏齒齔齕齗齟齡齙齠齜齦齬齪齲齷龍龔龕龜痠';
+const oc2tc = {
+ "床": "牀",
+ "為": "爲",
+ "產": "産",
+ '眾': '衆',
+ '寧': '甯',
+ '啟': '啓',
+ '鏽': '銹',
+ '閱': '閲',
+ '顏': '顔',
+ '嘆': '歎',
+ '線': '缐綫',
+ '綠': '緑',
+ '幸': '倖',
+ '聽': '聼聴'
+};
+const sc2tc = {
+ '巨':[
+ '巨',
+ ['鉅','巨款','巨富','巨细','巨子']
+ ],
+ '折':[
+ '折',
+ ['摺','折叠','折纸','存折','对折','折痕','奏折','折页','折扇']
+ ],
+ '霉':[
+ '霉',
+ ['黴','青霉素','红霉素','霉菌','氯霉素','绿霉素']
+ ],
+ '捆':[
+ '捆',
+ ['綑','捆绑','捆扎']
+ ],
+ '升':[
+ '升',
+ ['昇','升华','提升','高升','歌舞升平']
+ ],
+ '划':[
+ '劃',
+ ['划','划龙舟','划船','划算','划不来']
+ ],
+ '姜':[
+ '姜',
+ ['薑','姜片','姜葱','生姜','姜汁','姜母鸭']
+ ],
+ '御':[
+ '禦',
+ ['御','御制','御用']
+ ],
+ '毁':[
+ '毀',
+ ['燬','烧毁','焚毁','炸毁','销毁'],
+ ['譭','诋毁','毁谤']
+ ],
+ '胡':[
+ '胡',
+ ['鬍','胡须','胡子','刮胡刀'],
+ ['衚','胡同']
+ ],
+ '须':[
+ '須',
+ ['鬚','剃须刀','胡须','须发','根须']
+ ],
+ '同':[
+ '同',
+ ['衕','衚衕']
+ ],
+ '叹':[
+ '歎',
+ ['嘆','悲叹','叹息','仰天长叹','叹惋']
+ ],
+ '荡':[
+ '蕩',
+ ['盪','空荡荡','回荡','动荡','荡漾','震荡']
+ ],
+ '凄':[
+ '淒',
+ ['悽','凄厉','凄惨','悲凄','凄苦']
+ ],
+ '栗':[
+ '栗',
+ ['慄','战栗','颤栗','不寒而栗']
+ ],
+ '沈':[
+ '沈',
+ ['瀋','沈阳']
+ ],
+ '苏':[
+ '蘇',
+ ['甦','复苏','苏醒']
+ ],
+ '卤':[
+ '滷',
+ ['鹵','卤钝','卤莽','粗卤','卤地']
+ ],
+ '准':[
+ '準',
+ ['准','批准','准许','不准','准予']
+ ],
+ '杯':[
+ '杯',
+ ['盃','奖杯','世界杯']
+ ],
+ '馈':[
+ '饋',
+ ['餽','馈赠']
+ ],
+ '向':[
+ '向',
+ ['嚮','向往','向导']
+ ],
+ '搜':[
+ '搜',
+ ['蒐','蒐集','蒐羅']
+ ],
+ '哗':[
+ '嘩',
+ ['譁','哗变','喧哗','哗众取宠']
+ ],
+ '够':[
+ '夠',
+ ['搆','够不到']
+ ],
+ '范':[
+ '范',
+ ['範','模范','范本','示范','规范','范围']
+ ],
+ '喂':[
+ '喂',
+ ['餵','喂养','喂饱','饲喂']
+ ],
+ '迹':[
+ '跡',
+ ['蹟','古迹','遗迹','事迹','奇迹','史迹']
+ ],
+ '佩':[
+ '佩',
+ ['珮','玉佩']
+ ],
+ '尸':[
+ '屍',
+ ['尸','尸位素餐']
+ ],
+ '泛':[
+ '泛',
+ ['氾','泛滥']
+ ],
+ '雕':[
+ '雕',
+ ['彫','雕刻','雕像','雕塑','精雕细琢','雕琢','冰雕']
+ ],
+ '核':[
+ '核',
+ ['覈','审核','核实','核准','核对','复核','核查']
+ ],
+ '困':[
+ '困',
+ ['睏','困倦','困意','犯困']
+ ],
+ '欲':[
+ '欲',
+ ['慾','欲望','情欲','私欲','贪欲','色欲']
+ ],
+ '致':[
+ '致',
+ ['緻','精致','细致']
+ ],
+ '梁':[
+ '梁',
+ ['樑','栋梁','桥梁']
+ ],
+ '占':[
+ '占',
+ ['佔','占用','占领','侵占','占为己有','强占','占有','抢占']
+ ],
+ '卜':[
+ '卜',
+ ['蔔','萝卜','胡萝卜']
+ ],
+ '托':[
+ '托',
+ ['託','拜托','托付','嘱托','托词','托辞','推托','委托','托病','信托','托梦','托孤','托故','托管','受托','寄托']
+ ],
+ '刮':[
+ '刮',
+ ['颳','刮风']
+ ],
+ '尽':[
+ '盡',
+ ['儘','尽快','尽早','尽可能','尽显','尽量','尽管']
+ ],
+ '汇':[
+ '匯',
+ ['彙','词汇','字汇','汇集','汇编','辞汇']
+ ],
+ '才':[
+ '才',
+ ['纔','刚才','方才','却才','恰才']
+ ],
+ '丑':[
+ '醜',
+ ['丑','小丑','丑角','乙丑','丁丑','己丑','辛丑','癸丑','副丑']
+ ],
+ '周':[
+ '周',
+ ['週','周报','周期','周会','周日','周刊','周波','周岁','周末','周考','一周','二周','三周','四周','五周','两周','双周刊','名剧周','黄金周','周休','周一','周二','周三','周四','周五','周六'],
+ ['賙','周济']
+ ],
+ '冲':[
+ '沖',
+ ['衝','冲奖','冲高','冲决','冲浪','冲子','冲力','冲要','冲破','冲口','冲顶','冲床','冲突','冲刺','冲金','冲模','冲撞','冲腾','冲锋','冲量','冲动','冲程','冲压','冲杀','冲激','冲击','俯冲','反冲','折冲','缓冲','脉冲','要冲','冲锋枪','冲孔机','冲劲','冲金点','冲压机','冲击波','反冲力','冲锋','横冲','冲冠','首当其冲']
+ ],
+ '恶':[
+ '惡',
+ ['噁','恶心']
+ ],
+ '发':[
+ '發',
+ ['發','发回'],
+ ['髮','发网','发际','发箍','发丝','发式','发带','发型','发卡','发妻','发指','发廊','发饰','发乳','发夹','发菜','发屋','发姐','发油','发套','发蜡','发鬓','发髻','发雕','发辫','发胶','发浆','一发','假发','健发','削发','卷发','握发','束发','染发','植发','栉发','毛发','毫发','烫发','理发','白发','短发','秀发','秃发','结发','美发','胎发','脱发','华发','落发','蓄发','护发','金发','银发','头发','驳发','鬓发','须发','发小','剃发令','洗发','发短心长','怒发冲冠','断发文身','被发','鹤发','黄发垂髫','擢发难数','庞眉皓发','披头散发','间不容发']
+ ],
+ '复':[
+ '復',
+ ['複','复诊','复印','复写','复查','复习','复式','复种','复姓','复核','复音','复决','复利','复眼','复句','复合','复果','复述','复胃','复本','复方','复验','复选','复赛','复议','复制','复检','复杂','复叶','复线','复诵','复视','复试','复数','复评','复审','繁复','重复','复元音','复读机','复辅音','复共轭的','合义复词','衍声复词','山重水复'],
+ ['覆','复電','批复','核复','禀复','答复','被复','赐复','颠复','倾复','函复','反复','回复','复亡','复函','复命','复审','复复','复败','复书','复核','复没','复灭','复舟']
+ ],
+ '鉴':[
+ '鑒',
+ ['鑑','鉴于','鉴识','鉴赏','鉴证','鉴真','鉴谅','鉴别','鉴定','鉴戒','人鉴','借鉴','印鉴','可鉴','品鉴','唐鉴','图鉴','年鉴','殷鉴','洞鉴','王鉴','评鉴','赏鉴','通鉴','风鉴','龟鉴','明通鉴','鉴往知来','鉴古推今','有鉴于此','渊鉴类函','引为鉴戒','之鉴','宝鉴','玉鉴','引以为鉴','手鉴']
+ ],
+ '历':[
+ '歷',
+ ['曆','历书','历象','历元','历法','公历','回历','国历','夏历','年历','弘历','挂历','日历','月历','校历','桌历','殷历','皇历','旧历','藏历','西历','农历','阴历','阳历','黄历','台历','万历帝','藏历年','陀历道','阳历年','七曜历','三统历','乾象历','天体历','太初历','格里历','统天历','行事历','农民历','农家历','戊寅元历']
+ ],
+ '链':[
+ '鏈',
+ ['鍊','链子','拉链','精链','锻链','项链','锁链','铁链']
+ ],
+ '签':[
+ '簽',
+ ['籤','签子','签诗','抽签','掣签','书签','标签','求签','牙签','竹签','贴标签','唐音统签','金瓶掣签','云笈七签']
+ ],
+ '闲':[
+ '閒',
+ ['閑','闲闲','熟闲','高闲','闲居','幽闲','逾闲']
+ ],
+ '赞':[
+ '贊',
+ ['讚','赞赏','赞佩','赞美','赞誉','赞歌','赞叹','赞许','赞扬','赞颂','赞语','按赞','盛赞','礼赞','称赞','夸赞','颂赞','点赞','赞不绝口']
+ ],
+ '钟':[
+ '鍾',
+ ['鐘','钟摆','钟点','钟乳','钟楼','钟头','钟鼎','分钟','丧钟','座钟','挂钟','摆钟','时钟','洪钟','空钟','编钟','诗钟','警钟','电钟','闹钟','点钟','钟点房','钟鼓','钟点工','钟鼎文','大钟寺','石钟乳','光学钟','原子钟','大本钟','大笨钟','宗周钟','平安钟','打卡钟','抖空钟','撞丧钟','救命钟','敲警钟','敲丧钟','潜水钟','生物钟','石英钟','自鸣钟','电子钟','钟鸣','晨钟','黄钟','撞钟']
+ ],
+ '只':[
+ '只',
+ ['隻','几只','一只','二只','两只','三只','四只','五只','六只','七只','八只','九只','十只','百只','千只','万只','形单影只','只言片语','只字不提'],
+ ['只','只有','只会','只管','只消','只当','只好','只要','只能','只会','只是','只怕','只得','只见','只顾','只许','只因','不只','仅只','只不过','只此一家','只欠东风','只争朝夕']
+ ],
+ '捂':[
+ '捂',
+ ['摀','紧捂']
+ ],
+ '咸':[
+ '鹹',
+ ['咸','咸阳','咸宜','咸丰','咸和','咸池','咸五','彭咸','季咸','阮咸','阿咸','巫咸','碧咸']
+ ],
+ '脏':[
+ '髒',
+ ['臟','脏器','脏腑','五脏','内脏','心脏','肝脏','肺脏','胃脏','胰脏','脺脏','脾脏','肾脏','腑脏','肠脏']
+ ],
+ '岳':[
+ '岳',
+ ['嶽','五岳','中岳','北岳','南岳','西岳','东岳','岳立']
+ ],
+ '云':[
+ '雲',
+ ['云','人云亦云','云云']
+ ],
+ '游':[
+ '遊',
+ ['游','游泳','游水','花游']
+ ],
+ '弥':[
+ '彌',
+ ['瀰','弥漫']
+ ],
+ '松':[
+ '鬆',
+ ['松','惺松','阿松','松树','松针','松果','松鼠','松林','松竹']
+ ],
+ '愈':[
+ '愈',
+ ['癒','不愈','初愈','已愈','康愈','愈合','未愈','治愈','病愈','痊愈','自愈','伤愈','愈疮','渐愈']
+ ],
+ '尝':[
+ '嘗',
+ ['嚐','品尝','浅尝辄止','卧薪尝胆']
+ ],
+ '斗':[
+ '斗',
+ ['鬥','不斗','久斗','互斗','仍斗','共斗','再斗','初斗','力斗','勇斗','博斗','又斗','合斗','吵斗','善斗','大斗','好斗','想斗','打斗','批斗','抓斗','抗斗','拆斗','拼斗','挑斗','接斗','搏斗','敢斗','文斗','斗一','斗上','斗不','斗久','斗了','斗他','斗你','斗倒','斗出','斗到','斗力','斗勇','斗去','斗口','斗命','斗嘴','斗在','斗垮','斗士','斗奇','斗她','斗妍','斗完','斗弄','斗得','斗心','斗忍','斗志','斗快','斗意','斗成','斗我','斗批','斗技','斗招','斗拳','斗掌','斗斗','斗智','斗棋','斗法','斗牛','斗狗','斗狠','斗眼','斗神','斗私','斗草','斗角','斗起','斗趣','斗酒','斗魂','智斗','暗斗','未斗','格斗','械斗','武斗','死斗','比斗','游斗','激斗','狠斗','猛斗','相斗','私斗','群斗','苦斗','虎斗','血斗','要斗','角斗','越斗','跟斗','迎斗','邀斗','酣斗','乱斗','内斗','别斗','剧斗','劲斗','夺斗','奋斗','厮斗','恶斗','战斗','斗来','斗个','斗传','斗剑','斗劲','斗胜','斗场','斗将','斗恶','斗战','斗擞','斗败','斗敌','斗杀','斗殴','斗气','斗争','斗兽','斗毕','斗舰','斗艺','斗艳','斗赢','斗输','斗过','斗鸡','斗饮','斗闹','斗鱼','斗丽','会斗','权斗','殴斗','决斗','争斗','独斗','竞斗','约斗','缠斗','罢斗','观斗','赌斗','较斗','连斗','门斗','双斗','颤斗','凤斗','斗!']
+ ],
+ '系':[
+ '系',
+ ['係','关系','系数'],
+ ['系','系统','系列','体系','派系','直系'],
+ ['繫','不系','劾系','心系','所系','拘系','擐系','系上','系乎','系了','系住','系囚','系妥','系心','系念','系手','系牢','系留','系腰','系膜','系起','颈系','连系','联系','维系','系马','系个','系块','系带','系怀','系挂','系于','系条','系绊','系紧','系缚','系绳','系缆','系脚','系辞','系铃','系颈','牵系','梦系','身系','腰系','背系','縻系']
+ ],
+ '舍':[
+ '捨',
+ ['舍','宿舍','寒舍','屋舍','舍下']
+ ],
+ '干':[
+ '幹',
+ ['乾','口干','吃干','吐干','吮干','吸干','吹干','呷干','喉干','喝干','嘴干','太干','干井','干似','干冰','干冷','干化','干咳','干咽','干品','干哥','干嚎','干土','干坤','干妹','干姊','干姐','干姜','干娘','干爹','干爸','干妈','干季','干巴','干布','干干','干式','干弟','干性','干料','干旱','干杯','干果','干枝','干枯','干柴','干梅','干沙','干泥','干洗','干涸','干渴','干焦','干熬','干燥','干爽','干球','干疤','干瘦','干眼','干瞪','干硬','干窘','干笑','干等','干粉','干耗','干肉','干股','干脆','干花','干草','干菜','干薪','干衣','干裂','干透','干酪','干醋','干隆','干面','弄干','很干','抹干','抽干','揩干','擦干','晾干','朝干','未干','杯干','果干','桑干','榨干','水干','流干','海干','滴干','炒干','烘干','烤干','焙干','焦干','煨干','熨干','略干','碗干','粉干','耗干','肉干','舔干','菜干','蒸干','速干','干儿','干哑','干呕','干坛','干孙','干尸','干搁','干晒','干净','干涩','干涧','干湿','干热','干烧','干瘪','干瘾','干发','干粮','干结','干丝','干声','干叶','干号','干货','干阳','干饭','拧干','晒干','极干','泪干','沥干','烧干','烩干','发干','笋干','绞干','阴干','难干','风干','饮干','饼干','鱼干','唇干'],
+ ['干','干系','天干','干涉','干扰','干戈','相干','干我什','干我事','干我的事','干你什','干你事','干你的事','干他什','干他事','干他的事','干她什','干她事','干她的事']
+ ],
+ '了':[
+ '了',
+ ['瞭','了望','了然','了解','了若指掌','了如指掌']
+ ],
+ '谷':[
+ '穀',
+ ['谷','低谷','山谷','谷峰','谷底']
+ ],
+ '仿':[
+ '仿',
+ ['倣','仿效'],
+ ['彷','仿佛','仿徉'],
+ ['徬','仿徨']
+ ],
+ '效':[
+ '效',
+ ['傚','模效','摹效','仿效','儆效','效尤','效法']
+ ],
+ '克':[
+ '克',
+ ['剋','克夫','克扣','克日','克星','克期','克死','克薄','生克','相克','冲克'],
+ ['刻','克苦']
+ ],
+ '吊':[
+ '吊',
+ ['弔','吊信','吊古','吊唁','吊奠','吊孝','吊客','吊影','吊念','吊慰','吊文','吊民','吊祭','哀吊','唁吊','盆吊','祭吊','陪吊','吊问','吊丧','吊场','吊书','吊词','吊诡','吊贺','吊钱','凭吊']
+ ],
+ '台':[
+ '臺',
+ ['颱','冬台','秋台','防台','台风','强台','轻台'],
+ ['檯','台凳','台子','台布','台面','吧台','抹台','揩台','球台','窗台','翻台','餐台','台历','台灯','台钟','书台','柜台','赌台','长台']
+ ],
+ '回':[
+ '回',
+ ['迴','北回','南回','回圈','回廊','回旋','回游','回翔','回避','峰回','巡回','迂回','回环','回纹','回绕','回肠','回荡','回銮','回响','回风','梦回','盘回','纡回','萦回','轮回','递回']
+ ],
+ '后':[
+ '後',
+ ['后','仙后','吕后','天后','太后','封后','帝后','废后','影后','后冠','后土','后妃','后稷','后羿','母后','王后','皇后','舞后','西后','艳后','韦后']
+ ],
+ '征':[
+ '征',
+ ['徵','代征','停征','像征','免征','咎征','征了','征人','征信','征候','征兆','征入','征兵','征募','征去','征友','征取','征召','征地','征婚','征引','征得','征收','征文','征求','征片','征用','征稿','征管','征聘','征象','征逐','征集','急征','性征','新征','特征','狂征','病征','稽征','考征','苛征','表征','象征','超征','魏征','带征','广征','强征','征个','征启','征敛','征状','征税','征粮','征纳','征缴','征诏','征询','征调','征财','征费','征赋','征购','征选','应征','横征','减征','滥征','纳征','缓征','联征','详征','诚征','课征','变征','开征','体征']
+ ],
+ '注':[
+ '注',
+ ['註','注解','备注','注脚','批注','注册','注定','校注','尾注','注销','标注','注释']
+ ],
+ '丰':[
+ '豐',
+ ['丰','三丰','丰姿','丰度','丰情','丰神','丰韵']
+ ],
+ '并':[
+ '並',
+ ['併','一并','不并','并入','并力','并合','并吞','并图','并拢','并案','并叠','并砌','并科','并负','并购','并赃','并除','并陇','侵并','兼并','合并','吞并','整并','归并','相并','砌并','被并','裁并','购并','双并']
+ ],
+ '念':[
+ '念',
+ ['唸','光念','念佛','念作','念到','念咒','念好','念完','念得','念念','念成','念法','敢念','念书','念给','念经','念诵','念过','念错','念点','没念']
+ ],
+ '借':[
+ '借',
+ ['藉','借以','借口','借故','慰借','狼借','借机','借词','凭借','蕴借']
+ ],
+ '志':[
+ '志',
+ ['誌','日志','网志','墓志铭','聊斋志异','三国志','杂志']
+ ],
+ '么':[
+ '麼',
+ ['么','老么','么女','么儿','么妹','么子','么弟']
+ ],
+ '布':[
+ '布',
+ ['佈','公布','分布','宣布','密布','布伏','布署','布兵','布告','布局','布施','布景','布置','布防','布雷','故布','散布','遍布','传布','布个','布坛','布导','布岗','布于','布满','布阵','广布','摆布','满布','发布','预布']
+ ],
+ '分':[
+ '分',
+ ['份','分量','身分']
+ ],
+ '里':[
+ '裡',
+ ['里','○里','一里','七里','三里','下里','九里','二里','五里','亚里','佳里','克里','全里','两里','八里','公里','六里','凯里','劈里','加里','北里','十里','千里','南里','卡里','吉里','哈里','哥里','啰里','四里','埔里','多里','少里','尤里','居里','峇里','布里','几里','底里','德里','拉里','故里','数里','斯里','普里','东里','格里','归里','波里','乌里','百里','稀里','罗里','英里','莫里','万里','苏里','里亚','里仁','里夫','里奥','里尼','里布','里拉','里昂','里根','里民','里尔','里科','里程','里约','里纳','里美','里肌','里兰','里路','里里','里长','西里','贝里','路里','道里','乡里','邻里','阿里','马里','0里','0里','1里','2里','3里','4里','5里','6里','7里','8里','9里']
+ ],
+ '面':[
+ '面',
+ ['麵','制面','吃面','拉面','拌面','揉面','杯面','油面','泡面','炒面','煮面','碗面','羹面','肉面','辣面','面店','面杖','面灰','面碗','面筋','面粉','面糊','面茶','面食','食面','寿面','杆面','凉面','汤面','烫面','发面','酱面','面价','面团','面厂','面摊','面汤','面线','面饺','面饼','面馆','面馍','面龟','饨面','卤面','麦面','干面','擀面']
+ ],
+ '烟':[
+ '煙',
+ ['菸','烟斗','吸烟','好烟','戒烟','抽烟','支烟','旱烟','根烟','烟商','烟客','烟枪','烟民','烟灰','烟瘾','烟草','烟酒','烟头','烟鬼','烟龄','禁烟','买烟','香烟']
+ ],
+ '蒙':[
+ '蒙',
+ ['濛','灰蒙','空蒙','蒙蒙','迷蒙','弥蒙','蒙雾'],
+ ['矇','欺蒙','蒙住','蒙叟','蒙敝','蒙昧','蒙混','蒙瞀','蒙瞢','蒙瞽','蒙蔽','蒙胧','蒙眬','蒙骗'],
+ ['懞','蒙懂']
+ ],
+ '表':[
+ '表',
+ ['錶','戴表','手表','秒表','腕表','表店','跳表','陀表','怀表','表带','表厂','表壳','表炼','表链','钟表','马表']
+ ],
+ '板':[
+ '板',
+ ['闆','老板']
+ ],
+ '卷':[
+ '卷',
+ ['捲','卷入','卷起','龙卷风','席卷','蛋卷','花卷','袭卷','卷款','卷发','卷走','卷进','卷曲','卷舌','烟卷']
+ ],
+ '酸':[
+ '酸',
+ ['痠','酸软','酸痛','腰酸背痛']
+ ],
+ '仇':[
+ '仇',
+ ['讎','复仇','仇恨','报仇','仇敌']
+ ],
+ '几':[
+ '幾',
+ ['几','窗明几净','窗明几洁','茶几']
+ ],
+ '背':[
+ '背',
+ ['揹','背负','背黑锅','背包']
+ ],
+ '衔':[
+ '銜',
+ ['啣','结草衔环','衔着']
+ ],
+ '构':[
+ '構',
+ ['搆','构陷','构思']
+ ]
+};
+//繁轉簡
+const tc2sc = {
+ '著':[
+ '着',
+ ['著','著名','著作','巨著','著稱','顯著','昭著','卓著','所著','著述','編著','著書','名著','原著','遺著','譯著','著譯','著:','著:','土著','論著','專著','日新月著','著有','合著','知著','著錄','著者','較著','頗著','文著','著文','自著','著成','著《','撰著','著撰','拙著','著明','著論','新著','著於','而著','雜著','著足','著花','醫著','聲著']
+ ],
+ '乾':[
+ '干',
+ ['乾','乾隆','乾卦','乾道','乾宅','乾造','乾之卦','乾為','「乾」','乾坤','乾元','乾剛','乾方','乾施','乾首','乾象','乾啟','幹鈞','乾化','乾心','幹居','乾符','乾暉','幹曜','乾風','乾雷','乾州','中乾','連乾','乾沒','桑乾','乾乾','花乾']
+ ],
+ '瞭':[
+ '瞭',
+ ['了','瞭望','瞭然','瞭解','瞭若指掌','瞭如指掌']
+ ]
+};
+let sc2tcComb = {
+ '香烟袅袅':'香煙裊裊',
+ '袅袅香烟':'裊裊香煙',
+ '补丁':'補靪',
+ '老挝':'寮國',
+ '沈阳':'瀋陽',
+ '战栗':'顫慄',
+ '豆蔻':'荳蔻',
+ '累累':'纍纍',
+ '阿里':'阿里',
+ '跟斗':'觔斗',
+ '筋斗':'筋斗',
+ '折冲':'折衝',
+ '梁折':'樑折',
+ '松干':'松幹',
+ '家伙':'傢伙',
+ '伙夫':'伙伕',
+ '游斗':'游鬥',
+ '回游':'迴游',
+ '云游':'雲遊',
+ '云宵':'雲霄',
+ '考卷发':'考卷發',
+ '发卷':'髮卷',
+ "烟卷":"菸卷",
+ "连卷":"連卷",
+ '鼠标':'滑鼠',
+ 'U盘':'隨身碟',
+ '硬盘':'硬碟',
+ '磁盘':'磁碟',
+ '软件':'軟體',
+ '操作系统':'作業系統',
+ '文件系统':'檔案系統',
+ '笔记本':'筆記型電腦',
+ '台式机':'桌上型電腦',
+ '网络':'網路',
+ '打印':'列印',
+ '复印':'影印',
+ '充电宝':'行動電源',
+ '排插':'延長綫',
+ '程序':'程式',
+ '光盘':'光碟',
+ '音频':'音訊',
+ '屏幕':'熒幕',
+ '卸载':'解除安裝',
+ '文件夹':'檔案夾',
+ '局域网':'區域網路',
+ '服务器':'伺服器',
+ '打伞':'撐傘',
+ '洗面奶':'洗面乳',
+ '洗发水':'洗髮乳',
+ '打底裤':'内搭褲',
+ '电饭煲':'電鍋',
+ '发卡':'髮夾',
+ '聊天群':'聊天視窗',
+ '普通话':'國語',
+ '简历':'履歷',
+ '公交车':'公車',
+ '打车':'叫車',
+ '出租车':'計程車',
+ '地铁':'捷運',
+ '自行车':'脚踏車',
+ '摩托车':'機車',
+ '巴士':'客運',
+ '奔驰':'賓士',
+ '挺好的':'滿好的',
+ '牛逼':'厲害',
+ '左拐':'左轉',
+ '竖的':'直的',
+ '让一下':'借過',
+ '凉水':'冰水',
+ '打包':'外帶',
+ '外卖':'外送',
+ '很火':'很紅',
+ '宾馆':'飯店',
+ '旅馆':'賓館',
+ '包间':'包廂',
+ '卫生间':'化妝室',
+ '幼儿园':'幼稚園',
+ '公安局':'警察局',
+ '饭店':'餐廳',
+ '酒店':'飯店',
+ '高校':'大學',
+ '写字楼':'辦公大樓',
+ '换乘站':'轉運站',
+ '豆腐脑':'豆花',
+ '菠萝':'鳳梨',
+ '薯片':'洋芋片',
+ '土豆':'馬鈴薯',
+ '花生':'土豆',
+ '芝士':'起司',
+ '猕猴桃':'奇異果',
+ '盒饭':'便當',
+ '夜宵':'宵夜',
+ '金枪鱼':'鮪魚',
+ '三文鱼':'鮭魚',
+ '番石榴':'芭樂',
+ '冰激淋':'冰淇淋',
+ '冰棍':'冰棒',
+ '快餐':'速食',
+ '格斗':'挌鬥',
+ '西红柿':'番茄',
+ '西兰花':'花椰菜',
+ '创可贴':'OK綳',
+ '输液':'打點滴',
+ '献血':'捐血',
+ 'B超':'超音波檢查',
+ '疯牛病':'狂牛病',
+ '台球':'撞球',
+ '乒乓球':'桌球',
+ '自由泳':'自由式',
+ '蛙泳':'蛙式',
+ '初中生':'國中生',
+ '本科生':'大學生',
+ '程序员':'程式設計師',
+ '传销':'直銷',
+ '宇航员':'太空人',
+ '超声波':'超音波',
+ '北京时间':'中原標準時間',
+ '保质期':'保存期限',
+ '甲肝':'A肝',
+ '乙肝':'B肝',
+ '丙肝':'C肝',
+ '塑料':'塑膠',
+ '够不到':'搆不到',
+ '够不着':'搆不着',
+ '舞娘':'舞孃',
+ '秋千':'鞦韆',
+ '拐杖':'枴杖',
+ '剩余':'賸餘',
+ '胡同':'衚衕',
+ '个旧':'箇舊',
+ '朱砂':'硃砂',
+ '知识产权':'智慧財產權'
+};
+var stDict = {}, tsDict = {};
+var sc2tcCombTree = {}, tc2scCombTree = {};
+
+function traditionalizedString(orgStr, format) {
+ if (!orgStr) return "";
+ var str = '', char;
+ for (var i = 0; i < orgStr.length; i++) {
+ char = orgStr.charAt(i);
+ let search = sc2tcCombTree[char], searchIndex = i, hasMatch = false, startIndex = i;
+ while (search && searchIndex < orgStr.length) {
+ let downTree = null;
+ if (searchIndex < orgStr.length - 1) {
+ downTree = search[orgStr.charAt(searchIndex + 1)];
+ }
+ if (!downTree) {
+ if (search.end) {
+ hasMatch = true;
+ i = searchIndex;
+ if (format === OutputFormat.NORMAL) {
+ str += search.end;
+ } else {
+ const originalText = orgStr.substring(startIndex, searchIndex + 1);
+ const convertedText = search.end;
+ if (format === OutputFormat.BRACKET && originalText !== convertedText) {
+ str += convertedText + '(' + originalText + ')';
+ } else if (format === OutputFormat.RUBY && originalText !== convertedText) {
+ str += '' + convertedText + '' + originalText + ' ';
+ } else {
+ str += convertedText;
+ }
+ }
+ }
+ break;
+ }
+ searchIndex++;
+ search = downTree;
+ }
+ if (hasMatch) {
+ continue;
+ }
+ if (char.charCodeAt(0) > 10000) {
+ var tChar = stDict[char], sc2tcItem = sc2tc[char];
+ if (tChar || sc2tcItem) {
+ var newChar = "";
+ if (sc2tcItem) {
+ if (sc2tcItem.length == 1) {
+ newChar = sc2tcItem;
+ } else {
+ var defaultChar = sc2tcItem[0], char_f = [], char_b = [], r = i;
+ while (--r >= 0 && char_f.length < 3) {
+ char_f.push(orgStr.charAt(r));
+ }
+ r = i;
+ while (++r < orgStr.length && char_b.length < 3) {
+ char_b.push(orgStr.charAt(r));
+ }
+ for (var j = 1; j < sc2tcItem.length; j++) {
+ var others = sc2tcItem[j], otherChar = others[0];
+ for (var k = 1; k < others.length; k++) {
+ var curOther = others[k], fadd = curOther.indexOf(char), badd = curOther.length - 1 - fadd, x = 0;
+ var processChar = char;
+ while (fadd-- > 0) {
+ if (!char_f[x]) break;
+ processChar = char_f[x] + processChar;
+ x++;
+ }
+ x = 0;
+ while (badd-- > 0) {
+ if (!char_b[x]) break;
+ processChar += char_b[x];
+ x++;
+ }
+ if (processChar.indexOf(curOther) != -1) {
+ newChar = otherChar;
+ break;
+ }
+ }
+ if (newChar) break;
+ }
+ if (!newChar) newChar = defaultChar;
+ }
+ } else {
+ newChar = tChar;
+ }
+ if (format === OutputFormat.BRACKET && char !== newChar) {
+ str += newChar + '(' + char + ')';
+ } else if (format === OutputFormat.RUBY && char !== newChar) {
+ str += '' + newChar + '' + char + ' ';
+ } else {
+ str += newChar;
+ }
+ } else str += char;
+ }
+ else str += char;
+ }
+ return str;
+}
+
+function traditionalized(input, options) {
+ options = options || {};
+ const format = options.format !== undefined ? options.format : OutputFormat.NORMAL;
+
+ // Handle null/undefined
+ if (input == null) return input;
+
+ // Handle string
+ if (typeof input === 'string') {
+ return traditionalizedString(input, format);
+ }
+
+ // Handle array
+ if (Array.isArray(input)) {
+ return input.map(item => traditionalized(item, options));
+ }
+
+ // Handle object
+ if (typeof input === 'object') {
+ const result = {};
+ for (const key in input) {
+ if (input.hasOwnProperty(key)) {
+ result[key] = traditionalized(input[key], options);
+ }
+ }
+ return result;
+ }
+
+ // Return other types as-is (number, boolean, etc.)
+ return input;
+}
+
+function simplizedString(orgStr, format) {
+ if (!orgStr) return "";
+ var str = '', char;
+ for (var i = 0; i < orgStr.length; i++) {
+ char = orgStr.charAt(i);
+ let search = tc2scCombTree[char], searchIndex = i, hasMatch = false, startIndex = i;
+ while (search && searchIndex < orgStr.length) {
+ let downTree = null;
+ if (searchIndex < orgStr.length - 1) {
+ downTree = search[orgStr.charAt(searchIndex + 1)];
+ }
+ if (!downTree) {
+ if (search.end) {
+ hasMatch = true;
+ i = searchIndex;
+ if (format === OutputFormat.NORMAL) {
+ str += search.end;
+ } else {
+ const originalText = orgStr.substring(startIndex, searchIndex + 1);
+ const convertedText = search.end;
+ if (format === OutputFormat.BRACKET && originalText !== convertedText) {
+ str += convertedText + '(' + originalText + ')';
+ } else if (format === OutputFormat.RUBY && originalText !== convertedText) {
+ str += '' + convertedText + '' + originalText + ' ';
+ } else {
+ str += convertedText;
+ }
+ }
+ }
+ break;
+ }
+ searchIndex ++;
+ search = downTree;
+ }
+ if (hasMatch) {
+ continue;
+ }
+ if (char.charCodeAt(0) > 10000) {
+ var sChar = tsDict[char], tc2scItem = tc2sc[char];
+ if (sChar || tc2scItem) {
+ var newChar = "";
+ if (tc2scItem) {
+ if (tc2scItem.length == 1) {
+ newChar = tc2scItem;
+ } else {
+ var defaultChar = tc2scItem[0], char_f = [], char_b = [], r = i;
+ while (--r >= 0 && char_f.length < 3) {
+ char_f.push(orgStr.charAt(r));
+ }
+ r = i;
+ while (++r < orgStr.length && char_b.length < 3) {
+ char_b.push(orgStr.charAt(r));
+ }
+ for (var j = 1; j < tc2scItem.length; j++) {
+ var others = tc2scItem[j], otherChar = others[0];
+ for (var k = 1; k < others.length; k++) {
+ var curOther = others[k], fadd = curOther.indexOf(char), badd = curOther.length - 1 - fadd, x = 0;
+ var processChar = char;
+ while (fadd-- > 0) {
+ if (!char_f[x]) break;
+ processChar = char_f[x] + processChar;
+ x++;
+ }
+ x = 0;
+ while (badd-- > 0) {
+ if (!char_b[x]) break;
+ processChar += char_b[x];
+ x++;
+ }
+ if (processChar.indexOf(curOther) != -1) {
+ newChar = otherChar;
+ break;
+ }
+ }
+ if (newChar) break;
+ }
+ if (!newChar) newChar = defaultChar;
+ }
+ } else {
+ newChar = sChar;
+ }
+ if (format === OutputFormat.BRACKET && char !== newChar) {
+ str += newChar + '(' + char + ')';
+ } else if (format === OutputFormat.RUBY && char !== newChar) {
+ str += '' + newChar + '' + char + ' ';
+ } else {
+ str += newChar;
+ }
+ } else str += char;
+ }
+ else str += char;
+ }
+ return str;
+}
+
+function simplized(input, options) {
+ options = options || {};
+ const format = options.format !== undefined ? options.format : OutputFormat.NORMAL;
+
+ // Handle null/undefined
+ if (input == null) return input;
+
+ // Handle string
+ if (typeof input === 'string') {
+ return simplizedString(input, format);
+ }
+
+ // Handle array
+ if (Array.isArray(input)) {
+ return input.map(item => simplized(item, options));
+ }
+
+ // Handle object
+ if (typeof input === 'object') {
+ const result = {};
+ for (const key in input) {
+ if (input.hasOwnProperty(key)) {
+ result[key] = simplized(input[key], options);
+ }
+ }
+ return result;
+ }
+
+ // Return other types as-is (number, boolean, etc.)
+ return input;
+}
+
+function detect(text) {
+ if (!text) return ChineseType.UNKNOWN;
+
+ for (let i = 0; i < text.length; i++) {
+ const char = text.charAt(i);
+ if (char.charCodeAt(0) > 10000) {
+ const scChar = tsDict[char];
+ if (scChar && scChar !== char) {
+ return ChineseType.TRADITIONAL;
+ }
+ }
+ }
+
+ for (let i = 0; i < text.length; i++) {
+ const char = text.charAt(i);
+ if (char.charCodeAt(0) > 10000) {
+ const tcChar = stDict[char];
+ if (tcChar && tcChar !== char) {
+ return ChineseType.SIMPLIFIED;
+ }
+ }
+ }
+
+ return ChineseType.UNKNOWN;
+}
+
+function stcasc(cache, custom, disableTerms) {
+ if (!cache) cache = {};
+ if (cache.sc2tcCombTree && cache.tc2scCombTree) {
+ sc2tcCombTree = cache.sc2tcCombTree;
+ tc2scCombTree = cache.tc2scCombTree;
+ } else {
+ if (disableTerms) sc2tcComb = {};
+ if (custom && custom.length) {
+ for (let sc in custom) {
+ sc2tcComb[sc] = custom[sc];
+ }
+ }
+ function makeCombTree(key, value) {
+ let curTree = sc2tcCombTree;
+ for (let i = 0; i < key.length; i++) {
+ let curKey = key.charAt(i);
+ let branch = curTree[curKey];
+ let newTree = {};
+ if (i == key.length - 1) {
+ newTree = {"end": value};
+ if (branch) {
+ branch.end = value;
+ }
+ }
+ if (branch) {
+ curTree = branch;
+ } else {
+ curTree[curKey] = newTree;
+ curTree = newTree;
+ }
+ }
+ curTree = tc2scCombTree;
+ for (let i = 0; i < value.length; i++) {
+ let curKey = value.charAt(i);
+ let branch = curTree[curKey];
+ let newTree = {};
+ if (i == value.length - 1) {
+ newTree = {"end": key};
+ if (branch) {
+ branch.end = key;
+ }
+ }
+ if (branch) {
+ curTree = branch;
+ } else {
+ curTree[curKey] = newTree;
+ curTree = newTree;
+ }
+ }
+ }
+ for (let key in sc2tcComb) {
+ let value = sc2tcComb[key];
+ if (Array.isArray(value)) {
+ value.forEach(v => {
+ makeCombTree(key, v);
+ });
+ } else {
+ makeCombTree(key, value);
+ }
+ }
+ cache.sc2tcCombTree = sc2tcCombTree;
+ cache.tc2scCombTree = tc2scCombTree;
+ }
+ if (cache.stDict && cache.tsDict) {
+ stDict = cache.stDict;
+ tsDict = cache.tsDict;
+ } else {
+ for (let i = 0; i < scStr.length; i++) {
+ let _sc = scStr[i];
+ let _tc = tcStr[i];
+ if (!stDict[_sc]) stDict[_sc] = _tc;
+ if (!tsDict[_tc]) tsDict[_tc] = _sc;
+ }
+ Object.keys(oc2tc).forEach(key => {
+ let ocList = oc2tc[key];
+ for (let i = 0; i < ocList.length; i++) {
+ let oc = ocList[i];
+ stDict[oc] = key;
+ tsDict[oc] = tsDict[key] || key;
+ }
+ })
+ cache.stDict = stDict;
+ cache.tsDict = tsDict;
+ }
+ return {simplized, traditionalized, detect, cache};
+}
+
+export default stcasc;
diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/test.js b/Switch Traditional Chinese and Simplified Chinese/lib/test.js
new file mode 100644
index 00000000000..55337889052
--- /dev/null
+++ b/Switch Traditional Chinese and Simplified Chinese/lib/test.js
@@ -0,0 +1,215 @@
+import stcasc, { ChineseType, OutputFormat } from './stcasc.lib.js';
+
+console.log('========== 简繁转换库测试 ==========\n');
+
+// 初始化
+const { traditionalized, simplized, detect } = stcasc();
+
+// 测试 1: 基础简体转繁体
+console.log('测试 1: 基础简体转繁体');
+const sc1 = '简繁转换 繁简切换 香烟 香烟袅袅 烟雾里 里长面子';
+const tc1 = traditionalized(sc1);
+console.log('输入:', sc1);
+console.log('输出:', tc1);
+console.log('');
+
+// 测试 2: 基础繁体转简体
+console.log('测试 2: 基础繁体转简体');
+const tc2 = '繁體中文 簡體中文';
+const sc2 = simplized(tc2);
+console.log('输入:', tc2);
+console.log('输出:', sc2);
+console.log('');
+
+// 测试 3: 检测简体中文
+console.log('测试 3: 检测简体中文');
+const text1 = '这是简体中文';
+const type1 = detect(text1);
+console.log('文本:', text1);
+console.log('类型:', type1 === ChineseType.SIMPLIFIED ? '简体中文' : '未知');
+console.log('枚举值:', type1);
+console.log('');
+
+// 测试 4: 检测繁体中文
+console.log('测试 4: 检测繁体中文');
+const text2 = '這是繁體中文';
+const type2 = detect(text2);
+console.log('文本:', text2);
+console.log('类型:', type2 === ChineseType.TRADITIONAL ? '繁体中文' : '未知');
+console.log('枚举值:', type2);
+console.log('');
+
+// 测试 5: 检测非中文
+console.log('测试 5: 检测非中文');
+const text3 = 'English Text';
+const type3 = detect(text3);
+console.log('文本:', text3);
+console.log('类型:', type3 === ChineseType.UNKNOWN ? '未知' : '中文');
+console.log('枚举值:', type3);
+console.log('');
+
+// 测试 6: 输出格式 - BRACKET(括号格式)
+console.log('测试 6: 输出格式 - BRACKET(括号格式)');
+const sc3 = '简体中文转换';
+const tc3 = traditionalized(sc3, { format: OutputFormat.BRACKET });
+console.log('输入:', sc3);
+console.log('输出:', tc3);
+console.log('');
+
+// 测试 7: 输出格式 - RUBY(HTML ruby标签格式)
+console.log('测试 7: 输出格式 - RUBY(HTML ruby标签格式)');
+const sc4 = '简体中文';
+const tc4 = traditionalized(sc4, { format: OutputFormat.RUBY });
+console.log('输入:', sc4);
+console.log('输出:', tc4);
+console.log('');
+
+// 测试 8: 繁体转简体 - BRACKET格式
+console.log('测试 8: 繁体转简体 - BRACKET格式');
+const tc5 = '繁體中文';
+const sc5 = simplized(tc5, { format: OutputFormat.BRACKET });
+console.log('输入:', tc5);
+console.log('输出:', sc5);
+console.log('');
+
+// 测试 9: 繁体转简体 - RUBY格式
+console.log('测试 9: 繁体转简体 - RUBY格式');
+const tc6 = '繁體中文';
+const sc6 = simplized(tc6, { format: OutputFormat.RUBY });
+console.log('输入:', tc6);
+console.log('输出:', sc6);
+console.log('');
+
+// 测试 10: 复杂文本转换 - 正常格式
+console.log('测试 10: 复杂文本转换 - 正常格式');
+const complex = '吃干面 把考卷发回来 卷发 知识产权';
+const complexTc = traditionalized(complex);
+console.log('输入:', complex);
+console.log('输出:', complexTc);
+console.log('');
+
+// 测试 11: 复杂文本转换 - BRACKET格式
+console.log('测试 11: 复杂文本转换 - BRACKET格式');
+const complexBracket = traditionalized(complex, { format: OutputFormat.BRACKET });
+console.log('输入:', complex);
+console.log('输出:', complexBracket);
+console.log('');
+
+// 测试 12: 术语转换
+console.log('测试 12: 术语转换');
+const terms = '软件 硬盘 网络 服务器 鼠标';
+const termsTc = traditionalized(terms);
+console.log('输入:', terms);
+console.log('输出:', termsTc);
+console.log('');
+
+// 测试 13: 混合文本
+console.log('测试 13: 混合文本');
+const mixed = 'This is 简体中文 and English';
+const mixedTc = traditionalized(mixed);
+console.log('输入:', mixed);
+console.log('输出:', mixedTc);
+console.log('');
+
+// ========== 新增测试:Array/Object 支持 ==========
+console.log('========== Array/Object 测试 ==========\n');
+
+// 测试 14: 转换数组(简体->繁体)
+console.log('测试 14: 转换数组(简体->繁体)');
+const arr1 = ['简体中文', '软件', '硬盘', 123, true, null];
+const arr1Tc = traditionalized(arr1);
+console.log('输入:', arr1);
+console.log('输出:', arr1Tc);
+console.log('');
+
+// 测试 15: 转换数组(繁体->简体)
+console.log('测试 15: 转换数组(繁体->简体)');
+const arr2 = ['繁體中文', '軟體', '硬碟', 456, false];
+const arr2Sc = simplized(arr2);
+console.log('输入:', arr2);
+console.log('输出:', arr2Sc);
+console.log('');
+
+// 测试 16: 转换对象(简体->繁体)
+console.log('测试 16: 转换对象(简体->繁体)');
+const obj1 = {
+ title: '简体中文标题',
+ description: '这是一个简体中文描述',
+ count: 100,
+ active: true,
+ tags: ['软件', '网络', '服务器']
+};
+const obj1Tc = traditionalized(obj1);
+console.log('输入:', JSON.stringify(obj1, null, 2));
+console.log('输出:', JSON.stringify(obj1Tc, null, 2));
+console.log('');
+
+// 测试 17: 转换对象(繁体->简体)
+console.log('测试 17: 转换对象(繁体->简体)');
+const obj2 = {
+ title: '繁體中文標題',
+ description: '這是一個繁體中文描述',
+ price: 99.99,
+ items: ['軟體', '硬碟']
+};
+const obj2Sc = simplized(obj2);
+console.log('输入:', JSON.stringify(obj2, null, 2));
+console.log('输出:', JSON.stringify(obj2Sc, null, 2));
+console.log('');
+
+// 测试 18: 转换嵌套数组
+console.log('测试 18: 转换嵌套数组');
+const nestedArr = [
+ '简体中文',
+ ['软件', '硬盘'],
+ [['网络', '服务器']]
+];
+const nestedArrTc = traditionalized(nestedArr);
+console.log('输入:', JSON.stringify(nestedArr));
+console.log('输出:', JSON.stringify(nestedArrTc));
+console.log('');
+
+// 测试 19: 转换嵌套对象
+console.log('测试 19: 转换嵌套对象');
+const nestedObj = {
+ user: {
+ name: '简体名称',
+ profile: {
+ bio: '这是简体中文简介',
+ skills: ['软件开发', '网络管理']
+ }
+ },
+ count: 42
+};
+const nestedObjTc = traditionalized(nestedObj);
+console.log('输入:', JSON.stringify(nestedObj, null, 2));
+console.log('输出:', JSON.stringify(nestedObjTc, null, 2));
+console.log('');
+
+// 测试 20: 数组转换 - BRACKET 格式
+console.log('测试 20: 数组转换 - BRACKET 格式');
+const arr3 = ['简体', '中文'];
+const arr3Bracket = traditionalized(arr3, { format: OutputFormat.BRACKET });
+console.log('输入:', arr3);
+console.log('输出:', arr3Bracket);
+console.log('');
+
+// 测试 21: 对象转换 - RUBY 格式
+console.log('测试 21: 对象转换 - RUBY 格式');
+const obj3 = {
+ text1: '简体',
+ text2: '中文'
+};
+const obj3Ruby = traditionalized(obj3, { format: OutputFormat.RUBY });
+console.log('输入:', JSON.stringify(obj3, null, 2));
+console.log('输出:', JSON.stringify(obj3Ruby, null, 2));
+console.log('');
+
+// 测试 22: 处理 null 和 undefined
+console.log('测试 22: 处理 null 和 undefined');
+console.log('null 输入:', traditionalized(null));
+console.log('undefined 输入:', traditionalized(undefined));
+console.log('包含 null 的数组:', traditionalized(['简体', null, '中文']));
+console.log('');
+
+console.log('========== 测试完成 ==========');
diff --git a/X-Downloader/X-Downloader.user.js b/X-Downloader/X-Downloader.user.js
new file mode 100644
index 00000000000..72531dfbd90
--- /dev/null
+++ b/X-Downloader/X-Downloader.user.js
@@ -0,0 +1,167 @@
+// ==UserScript==
+// @name X-Downloader-Script
+// @name:zh-CN X-Downloader-Script
+// @name:zh-TW X-Downloader-Script
+// @name:ja X-Downloader-Script
+// @namespace hoothin
+// @version 2025-08-18
+// @license MIT
+// @description Enhances your Twitter (X) experience by adding a convenient download button to images and videos (GIFs), enabling easy, one-click saving of media.
+// @description:zh-CN 优化你的推特 (X) 浏览体验,直接在图片和视频(GIF)上添加一个便捷的下载按钮,一键轻松保存喜欢的媒体内容。
+// @description:zh-TW 優化您的 Twitter (X) 瀏覽體驗,直接在圖片及影片(GIF)上新增一個便捷的下載按鈕,一鍵輕鬆儲存喜愛的媒體內容。
+// @description:ja Twitter (X) の画像や動画(GIF)に便利なダウンロードボタンを追加し、ワンクリックでお気に入りのメディアを簡単に保存できるようにします。
+// @author hoothin
+// @match https://x.com/*
+// @match https://twitter.com/*
+// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
+// @grant none
+// @downloadURL https://update.greasyfork.org/scripts/545186/X-Downloader-Script.user.js
+// @updateURL https://update.greasyfork.org/scripts/545186/X-Downloader-Script.meta.js
+// ==/UserScript==
+
+(function() {
+ 'use strict';
+ let downloadBtn = document.createElement("a"), touch = false, simpleClick = false;
+ downloadBtn.target = "_blank";
+ downloadBtn.style.cssText = "background: #000000aa; border-radius: 50%; transition: opacity ease 0.3s; position: absolute; top: 0; right: 0px; cursor: pointer; opacity: 0; padding: 5px;";
+ downloadBtn.innerHTML = ` `;
+ downloadBtn.addEventListener("mousedown", e => {
+ let parent = downloadBtn.parentNode;
+ if (!parent) return;
+ simpleClick = false;
+ let img = parent.querySelector('[data-testid="tweetPhoto"]>img,[data-testid="card.layoutLarge.media"] img');
+ if (img) {
+ let newsrc = img.src.replace("_normal.",".").replace("_200x200.",".").replace("_mini.",".").replace("_bigger.",".").replace(/_x\d+\./,"."), imgname;
+ if (/\.svg$/.test(newsrc)) return;
+ if (newsrc == img.src) {
+ newsrc=newsrc.replace(/\?format=/i, ".").replace(/\&name=/i, ":").replace(/\.(?=[^\.\/]*$)/, "?format=").replace( /(:large|:medium|:small|:orig|:thumb|:[\dx]+)/i, "");
+ if (newsrc != img.src) {
+ newsrc = newsrc + "&name=orig";
+ }
+ }
+ while(parent) {
+ if (parent.nodeName == "ARTICLE" && parent.dataset && parent.dataset.testid == "tweet") {
+ break;
+ }
+ parent = parent.parentNode;
+ }
+ if (parent) {
+ const time = parent.querySelector('time[datetime]');
+ const user = parent.querySelector('[role="link"]>div>div>span>span');
+ let formatMatch = img.src.match(/format=(\w+)/), ext = "jpg";
+ if (formatMatch) {
+ ext = formatMatch[1];
+ } else {
+ formatMatch = newsrc.match(/\.(\w+)/);
+ if (formatMatch) {
+ ext = formatMatch[1];
+ }
+ }
+ imgname = `${user.innerText} ${time.innerText.replace(/(.*) · (.*)/, "$2 $1")}.${ext}`;
+ }
+ downloadBtn.href = newsrc;
+ if ((e.button === 0 && !e.ctrlKey) || touch) {
+ simpleClick = true;
+ downloadByFetch(newsrc, imgname);
+ }
+ } else {
+ while(parent) {
+ if (parent.nodeName == "ARTICLE" && parent.dataset && parent.dataset.testid == "tweet") {
+ break;
+ }
+ parent = parent.parentNode;
+ }
+ if (parent) {
+ downloadBtn.removeAttribute('download');
+ let link = parent.querySelector('a[role="link"][aria-label][href^="/"]');
+ downloadBtn.href = `https://twitter.luopo.org/?url=${encodeURIComponent(link ? link.href : document.location.href)}`;
+ if (e.altKey || touch) {
+ window.open(downloadBtn.href, "_blank");
+ }
+ }
+ }
+ });
+ downloadBtn.addEventListener("click", e => {
+ if (simpleClick || e.altKey || touch) {
+ e.preventDefault();
+ e.stopPropagation();
+ }
+ });
+ downloadBtn.addEventListener("mouseenter", () => {
+ downloadBtn.style.opacity = 1;
+ });
+ downloadBtn.addEventListener("mouseleave", () => {
+ setTimeout(() => {
+ downloadBtn.style.opacity = 0.1;
+ }, 100);
+ });
+ async function downloadByFetch(imageUrl, filename) {
+ try {
+ const response = await fetch(imageUrl);
+ if (!response.ok) throw new Error('CORS request failed');
+ const blob = await response.blob();
+ const blobUrl = URL.createObjectURL(blob);
+ const tempLink = document.createElement('a');
+ tempLink.href = blobUrl;
+ tempLink.setAttribute('download', filename);
+ document.body.appendChild(tempLink);
+ tempLink.click();
+ document.body.removeChild(tempLink);
+ URL.revokeObjectURL(blobUrl);
+ } catch (error) {
+ console.error('error:', error);
+ window.open(imageUrl, '_blank');
+ }
+ }
+ const show = (ele) => {
+ ele.appendChild(downloadBtn);
+ setTimeout(() => {
+ downloadBtn.style.opacity = touch ? 0.8 : 0.6;
+ }, 0);
+ };
+ const addBtn = e => {
+ if (e.target.dataset && e.target.dataset.testid == "card.layoutLarge.media") {
+ show(e.target.parentNode);
+ } else if (e.target.dataset && e.target.dataset.testid == "tweetPhoto") {
+ show(e.target.parentNode);
+ } else if (e.target.dataset && /^video\-player/.test(e.target.dataset.testid)) {
+ show(e.target.parentNode);
+ } else if (e.target.parentNode && e.target.parentNode.dataset && e.target.parentNode.dataset.testid == "tweetPhoto") {
+ show(e.target.parentNode.parentNode);
+ }
+ };
+ function isElementVisible(el) {
+ const rect = el.getBoundingClientRect();
+ return rect.top < window.innerHeight && rect.top > 0 && rect.bottom >= 0;
+ }
+ function findFirstVisibleElement(selector) {
+ const elements = document.querySelectorAll(selector);
+ const firstVisibleElement = Array.from(elements).find(el => {
+ return isElementVisible(el);
+ });
+ return firstVisibleElement;
+ }
+ let checkTimer;
+ const touchCheck = e => {
+ clearTimeout(checkTimer);
+ if (e.target == downloadBtn) return;
+ checkTimer = setTimeout(() => {
+ if (isElementVisible(downloadBtn)) return;
+ let target = findFirstVisibleElement("[data-testid='card.layoutLarge.media']");
+ if (target) {
+ return show(target.parentNode);
+ }
+ target = findFirstVisibleElement("[data-testid='tweetPhoto']");
+ if (target) {
+ return show(target.parentNode);
+ }
+ target = findFirstVisibleElement("[data-testid^='video-player']");
+ if (target) {
+ return show(target.parentNode);
+ }
+ }, 100);
+ };
+ document.addEventListener("mouseenter", addBtn, true);
+ document.addEventListener("touchstart", e => {touch = true; addBtn(e);}, true);
+ document.addEventListener("touchend", touchCheck, true);
+})();
\ No newline at end of file