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 f5e42694275..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 new file mode 100644 index 00000000000..01911cc1730 --- /dev/null +++ b/.github/workflows/json-validator.yml @@ -0,0 +1,21 @@ +name: Validate JSON + +on: + pull_request: + paths: + - 'Pagetual/pagetualRules.json' + +jobs: + validate-json: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: json-yaml-validate + uses: GrantBirki/json-yaml-validate@v5 + id: json-yaml-validate + with: + json_schema: Pagetual/pagetual.schema.json + files: | + 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/Appinn Comment/AppinnComment.user.js b/Appinn Comment/AppinnComment.user.js new file mode 100644 index 00000000000..46076e191bc --- /dev/null +++ b/Appinn Comment/AppinnComment.user.js @@ -0,0 +1,46 @@ +// ==UserScript== +// @name Appinn comment +// @name:zh-CN 小众软件评论显示 +// @namespace hoothin +// @version 2024-06-08 +// @description Display the comments from the Appinn forum on the bottom of the corresponding page on the main site. +// @description:zh-CN 将小众软件论坛的评论内容显示在主站对应页面下部 +// @author hoothin +// @match https://www.appinn.com/* +// @icon data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw== +// @grant GM_xmlhttpRequest +// @connect meta.appinn.net +// @downloadURL https://update.greasyfork.org/scripts/497293/Appinn%20comment.user.js +// @updateURL https://update.greasyfork.org/scripts/497293/Appinn%20comment.meta.js +// ==/UserScript== + +(function() { + 'use strict'; + const commentLink = document.querySelector('a.wpdc-join-discussion-link'); + if (!commentLink) return; + GM_xmlhttpRequest({ + url: commentLink.href, + method: 'GET', + onload: function(res) { + try { + let doc = document.implementation.createHTMLDocument(''); + doc.documentElement.innerHTML = res.response; + let dataPreloaded = doc.getElementById('data-preloaded'); + if (!dataPreloaded) return; + dataPreloaded = JSON.parse(JSON.parse(dataPreloaded.dataset.preloaded)["topic_" + commentLink.href.match(/\d+/)[0]]).post_stream.posts; + let posts = document.createElement("ul"); + posts.style.maxHeight = '90vh'; + posts.style.overflow = 'auto'; + posts.style.margin = '0'; + let title = document.createElement("h3"); + title.innerText = "评论内容"; + document.querySelector('article').appendChild(title); + document.querySelector('article').appendChild(posts); + dataPreloaded.forEach(item => { + posts.innerHTML += `
  • ${item.display_username || item.username}

    ${item.cooked}
  • `; + }); + } catch (e) { + } + } + }); +})(); \ No newline at end of file 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 4f64692cb00..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.5 +// @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,12 +271,14 @@ if (window.top != window.self) { dacSaveAsZip:"下载为 zip", dacSetCustomRule:"修改规则", dacAddUrl:"添加章节", + prefix:"给章节名称添加前缀", dacStartDownload:"下载选中", - downloadShortcut:"下载章节", - downloadSingleShortcut:"下载单页", - downloadCustomShortcut:"自定义下载" + downloadShortcut:"下载章节快捷键", + downloadSingleShortcut:"下载单页快捷键", + downloadCustomShortcut:"自定义下载快捷键" }; break; + case "zh": case "zh-TW": case "zh-HK": i18n={ @@ -290,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:"儲存設定", @@ -311,10 +323,129 @@ if (window.top != window.self) { dacSaveAsZip:"下載為 zip", dacSetCustomRule:"修改規則", dacAddUrl:"新增章節", + prefix:"為章節名稱加上前綴", dacStartDownload:"下載選取", - downloadShortcut:"下載章節", - downloadSingleShortcut:"下載單頁", - downloadCustomShortcut:"自設下載" + downloadShortcut:"下載章節快速鍵", + downloadSingleShortcut:"下載單頁快速鍵", + downloadCustomShortcut:"自設下載快速鍵" + }; + break; + case "ar": + case "ar-AE": + case "ar-BH": + case "ar-DZ": + case "ar-EG": + case "ar-IQ": + case "ar-JO": + case "ar-KW": + case "ar-LB": + case "ar-LY": + case "ar-MA": + case "ar-OM": + case "ar-QA": + case "ar-SA": + case "ar-SY": + case "ar-TN": + case "ar-YE": + i18n={ + 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: @@ -334,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", @@ -355,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 @@ -450,7 +594,7 @@ if (window.top != window.self) { filterListContainer = document.createElement("div"); filterListContainer.id = "filterListContainer"; filterListContainer.innerHTML = createHTML(` -
    +
    ${i18n.custom} @@ -706,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; @@ -723,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); @@ -740,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(` ')", @@ -760,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);", @@ -777,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);", @@ -824,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", @@ -935,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);", @@ -952,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);", @@ -969,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", @@ -1108,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动漫 - 分類", @@ -1193,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))", @@ -1362,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" @@ -1443,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", @@ -1482,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", @@ -1568,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", @@ -1615,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", @@ -1680,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", @@ -1730,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", @@ -1790,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", @@ -1883,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", @@ -1900,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", @@ -1929,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", @@ -2026,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", @@ -2284,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", @@ -2358,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": "美女目录网 - 圖片", @@ -2457,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", @@ -2679,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", @@ -2691,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 - 看圖禁用", @@ -2935,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", @@ -3004,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", @@ -3052,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", @@ -3084,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']", @@ -3106,7 +2503,7 @@ "name": "PPP.Porn - 首頁(載入更多 …)", "author": "skofkyo", "example": "https://ppp.porn/", - "url": "^https?://ppp\\.porn/$", + "url": "^https?://ppp\\.porn/", "loadMore": ".btn.btn--sm" }, { @@ -3120,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", @@ -3222,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()}})", @@ -3304,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;", @@ -3353,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']]", @@ -3369,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", @@ -3395,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", @@ -3440,9 +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;}" + "css": "#img {max-width: 100% !important;height: auto !important;min-height: 400px;}", + "pageInit": "let img=doc.getElementById('img');img&&img.setAttribute('onerror','setTimeout(()=>{this.src=this.src.replace(/(\\\\?time=.*)?$/,`?time=${Date.now()}`)},3000)');" }, { "name": "177 漫画/xxiav - 圖片", @@ -3501,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", @@ -3680,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" @@ -3739,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", @@ -3798,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", @@ -3826,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", @@ -3875,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" }, @@ -3927,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", @@ -3947,14 +3283,19 @@ "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": "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": "韩漫天堂漫画", + "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": "YouJizz", @@ -3972,121 +3313,29 @@ "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": "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": "xHamster channels", - "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 -}, -{ - "name": "xHamster creators", - "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 + "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": "色色啦", @@ -4103,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", @@ -4192,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" }, { @@ -4200,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", @@ -4232,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", @@ -4293,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", @@ -4383,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", @@ -4409,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", @@ -4442,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", @@ -4473,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", @@ -4514,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>*", @@ -4543,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", @@ -4658,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", @@ -4705,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", @@ -4776,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": "丽图·污漫画 - 分類", @@ -4786,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": "海棠小说网 - 手机阅读", @@ -4835,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 }, { @@ -4862,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 }, { @@ -4879,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": "國模網", @@ -4901,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", @@ -4979,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 }, { @@ -5033,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", @@ -5261,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", @@ -5303,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", @@ -5342,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, @@ -5379,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,'')", @@ -5435,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", @@ -5447,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" @@ -5465,7 +4394,10 @@ "name": "Yandex", "url": "^https?://yandex\\.(com|ru)/search/", "pageElement": "#search-result>li", - "pageElementCss": "content-visibility:visible" + "pageElementCss": "content-visibility:visible", + "css": "inIframe:.HeaderDesktop{display:none;}", + "action": 2, + "fitWidth": false }, { "name": "yandex web search mobile", @@ -5497,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", @@ -5543,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$", @@ -5567,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" @@ -5607,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); }}}" }, { @@ -5619,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": "图书书目检索", @@ -5766,7 +4709,7 @@ "a.prev" ], "pageNum": "\\-\\d+\\-{$p}\\.html", - "pageElement": "div#threadlist form", + "pageElement": "div#threadlist>div>form", "replaceElement": "#pgt div.pg" }, { @@ -5794,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", @@ -5822,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 }, { @@ -5845,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 " }, { @@ -5854,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 @@ -6113,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", @@ -6151,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": "魂+列表页", @@ -6171,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": "动漫啦", @@ -6183,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, @@ -6222,7 +5191,7 @@ }, { "name": "什么值得买社区", - "action": 0, + "action": 1, "url": "^https://post\\.smzdm\\.com/p", "pageElement": "#comment", "nextLink": ".pagedown>a" @@ -6391,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列表页", @@ -6521,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", @@ -6541,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, @@ -6785,7 +5771,15 @@ { "name": "Ru.Board", "url": "^https?://forum\\.ru-board\\.com/", - "nextLink": "table .small>b+a" + "nextLink": "table .small>b+a", + "exclude": "table.tb" +}, +{ + "name": "Ru.Board", + "url": "^https?://forum\\.ru-board\\.com/", + "nextLink": "table .small>b+a", + "pageElement": "table.tb", + "include": "table.tb" }, { "name": "淘宝已买到的宝贝", @@ -7026,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 @@ -7164,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/", @@ -7193,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/$", @@ -7203,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", @@ -7334,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/", @@ -7381,7 +6424,8 @@ "example": "https://myanimelist.net/topanime.php", "nextlink": "icon-top-ranking-page-bottom> .link-blue-box.next", "replaceElement": ".link-blue-box", - "pageElement": ".top-ranking-table" + "pageElement": ".top-ranking-table", + "action": 2 }, { "name": "MAL - recommendations", @@ -7411,5 +6455,48 @@ "pageElement": ".leftnav+td>*", "pageAction": "eles.forEach(ele=>{let portalImg=ele.querySelector('var.portalImg');if(!portalImg)return;portalImg.innerHTML=``})", "action": 0 +}, +{ + "name": "Linux Mint Forums", + "url": "^https://forums\\.linuxmint\\.com", + "example": "https://forums.linuxmint.com/https://forums.linuxmint.com/viewforum.php?f=225&sid=68c4b0d85f3ce4c5f9d925204808e035", + "nextlink": "div[class$='bar-top'] > .pagination > ul > li[class='arrow next'] > a", + "replaceElement": "div[class$='bar-bottom'] > .pagination", + "pageElement": "div[class='forumbg'] > .inner> ul[class='topiclist topics']", + "action": 1 +}, +{ + "name": "楽天ウェブ検索", + "url": "^https?://websearch\\.rakuten\\.co\\.jp/", + "example": "https://websearch.rakuten.co.jp/Web?qt=pagetual&st=20&col=OW", + "author": "Hoothin", + "nextLinkByUrl": [ + "st=(\\d+)", + "st={$1+10}" + ], + "action": 0, + "pageElement":".web-result>li", + "pagePre": "let evalData=response.match(/\\*{let ele=document.createElement('li');ele.innerHTML=`
  • ${item.title}


    ${item.summary}

  • `;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 d6b24041cf0..e2a9fee008a 100644 --- a/Pagetual/version +++ b/Pagetual/version @@ -1 +1 @@ -19 +109 diff --git a/Picviewer CE+/Picviewer CE+.user.js b/Picviewer CE+/Picviewer CE+.user.js index 2ea33edcc6e..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.5.29.1 +// @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/1384302/pvcep_rules.js -// @require https://update.greasyfork.org/scripts/440698/1383389/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; @@ -946,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; @@ -1124,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', @@ -1219,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()){ @@ -1277,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){ @@ -1353,7 +1370,7 @@ let autoInput = createCheckbox('總是自動切換', auto); let notificationInput = createCheckbox('切換成功通知', notification); let enablePinyinInput = createCheckbox('啟用拼音顯示', !disablePinyin); - let keyCallNotSaveInput = createCheckbox('用快捷鍵切換時不記錄選擇', keyCallNotSave); + let keyCallNotSaveInput = createCheckbox('用快速鍵切換時不記憶選擇', keyCallNotSave); let defaultSimple = document.createElement('select'); let cnOption = document.createElement('option'); @@ -1381,7 +1398,7 @@ shortcutCon.style.alignItems = 'center'; let shortcutTitle = document.createElement('h3'); shortcutTitle.style.margin = '5px 0'; - shortcutTitle.innerText = '繁簡切換快捷鍵:'; + shortcutTitle.innerText = '繁簡切換快速鍵:'; shortcutCon.appendChild(shortcutTitle); let shortcutInput = document.createElement('input'); shortcutInput.style.height = '20px'; @@ -1410,7 +1427,7 @@ pinyinShortcutCon.style.alignItems = 'center'; let pinyinShortcutTitle = document.createElement('h3'); pinyinShortcutTitle.style.margin = '5px 0'; - pinyinShortcutTitle.innerText = '顯示拼音快捷鍵:'; + pinyinShortcutTitle.innerText = '顯示拼音快速鍵:'; pinyinShortcutCon.appendChild(pinyinShortcutTitle); let pinyinShortcutInput = document.createElement('input'); pinyinShortcutInput.style.height = '20px'; @@ -1484,7 +1501,7 @@ let customTermTitle = document.createElement('h3'); customTermTitle.style.margin = '5px 0'; - customTermTitle.innerText = '自定義簡繁用語轉換(可透過通配符設置生效網址範圍):'; + customTermTitle.innerText = '自訂簡繁用語轉換(可透過通配符設定生效網址範圍):'; let addNewGlob1 = document.createElement('button'); addNewGlob1.innerText = '添加生效網站'; @@ -1556,7 +1573,7 @@ let customIlliteracyTitle = document.createElement('h3'); customIlliteracyTitle.style.margin = '5px 0'; - customIlliteracyTitle.innerText = '通用字詞轉換(可透過通配符設置生效網址範圍):'; + customIlliteracyTitle.innerText = '通用字詞轉換(可透過通配符設定生效網址範圍):'; let addNewGlob2 = document.createElement('button'); addNewGlob2.innerText = '添加生效網站'; addNewGlob2.addEventListener("click", function(e) { @@ -1648,7 +1665,7 @@ }); let buttonCon = document.createElement('div'); let saveBtn = document.createElement('button'); - saveBtn.innerText = '保存設置'; + saveBtn.innerText = '保存設定'; saveBtn.style.display = 'block'; saveBtn.style.fontSize = 'x-large'; saveBtn.style.fontWeight = 'bold'; @@ -1711,17 +1728,21 @@ 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', ""); storage.setItem('fuckIlliteracyTree', ""); - alert('保存設置成功!'); + alert('保存設定成功!'); location.reload(); }); buttonCon.appendChild(saveBtn); @@ -1754,7 +1775,7 @@ baseCon.appendChild(testTitle); let testInput = document.createElement('textarea'); testInput.style.width = '100%'; - testInput.setAttribute('placeholder', "輸入文字后,按下快捷鍵"); + testInput.setAttribute('placeholder', "輸入文字后,按下快速鍵"); testInput.onclick = e => { if (!testInput.style.height) { testInput.style.height = "80vh"; @@ -1883,39 +1904,54 @@ sc2tcCombTree = values.sc2tcCombTree; tc2scCombTree = values.tc2scCombTree; } else { - for(let key in sc2tcComb){ - let value=sc2tcComb[key]; + function makeCombTree(key, value) { let curTree=sc2tcCombTree; for(let i=0;i { + makeCombTree(key, v); + }); + } else { + makeCombTree(key, value); + } + } storage.setItem("sc2tcCombTree", sc2tcCombTree); storage.setItem("tc2scCombTree", tc2scCombTree); } diff --git a/Switch Traditional Chinese and Simplified Chinese/lib/package.json b/Switch Traditional Chinese and Simplified Chinese/lib/package.json new file mode 100644 index 00000000000..489310114ed --- /dev/null +++ b/Switch Traditional Chinese and Simplified Chinese/lib/package.json @@ -0,0 +1,70 @@ +{ + "name": "switch-chinese", + "version": "1.0.16", + "description": "繁簡轉換,支援簡繁雙向轉換、智慧分詞、自訂詞庫、文字偵測及多種輸出格式,零依賴。 Lightweight Chinese converter library for conversion between Simplified and Traditional Chinese. 轻量级简繁体中文智能转换库,支持简繁双向转换、智能分词、自定义词库、文本检测及多种输出格式,零依赖。", + "main": "stcasc.lib.js", + "types": "stcasc.d.ts", + "type": "module", + "exports": { + ".": { + "import": "./stcasc.lib.js", + "types": "./stcasc.d.ts" + } + }, + "files": [ + "stcasc.lib.js", + "stcasc.d.ts", + "readme.md" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/hoothin/UserScripts.git#master" + }, + "keywords": [ + "chinese", + "converter", + "traditional", + "simplified", + "chinese-converter", + "simplified-chinese", + "traditional-chinese", + "chinese-translation", + "chinese-detection", + "character-detection", + "text-converter", + "language-converter", + "i18n", + "localization", + "ruby-annotation", + "简繁转换", + "簡繁轉換", + "简繁切换", + "簡繁切換", + "繁简转换", + "繁簡轉換", + "繁简切换", + "繁簡切換", + "简体中文", + "繁体中文", + "簡體中文", + "繁體中文", + "正體中文", + "中文转换", + "中文检测", + "一简多繁", + "智能分词", + "自定义词库", + "零依赖", + "轻量级" + ], + "author": "Hoothin", + "license": "MIT", + "bugs": { + "url": "https://github.com/hoothin/UserScripts/issues" + }, + "homepage": "https://github.com/hoothin/UserScripts/tree/master/Switch%20Traditional%20Chinese%20and%20Simplified%20Chinese/lib", + "engines": { + "node": ">=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) + +--- + +## 简体中文 + +简繁体中文转换库 - 支持简体中文与繁体中文双向转换,基于词组的智能分词处理「一简多繁」问题 + +[![NPM](https://img.shields.io/npm/v/switch-chinese.svg)](https://www.npmjs.com/package/switch-chinese) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](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. + +[![NPM](https://img.shields.io/npm/v/switch-chinese.svg)](https://www.npmjs.com/package/switch-chinese) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](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 + +--- + +## 繁體中文 + +簡繁體中文智能轉換庫 - 支援簡體中文與正體中文雙向轉換,基於詞組的智能分詞處理「一簡多繁」問題 + +[![NPM](https://img.shields.io/npm/v/switch-chinese.svg)](https://www.npmjs.com/package/switch-chinese) [![License](https://img.shields.io/badge/license-MIT-brightgreen.svg)](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/Switch Traditional Chinese and Simplified Chinese/\347\260\241\347\271\201\350\275\211\346\217\233 by Ch'\303\274 Ts\303\252-t'ien.json" "b/Switch Traditional Chinese and Simplified Chinese/\347\260\241\347\271\201\350\275\211\346\217\233 by Ch'\303\274 Ts\303\252-t'ien.json" new file mode 100644 index 00000000000..2c544d2a232 --- /dev/null +++ "b/Switch Traditional Chinese and Simplified Chinese/\347\260\241\347\271\201\350\275\211\346\217\233 by Ch'\303\274 Ts\303\252-t'ien.json" @@ -0,0 +1,1665 @@ +{ + "*": { + "群": "群", + "香烟袅袅": "香煙裊裊", + "袅袅香烟": "裊裊香煙", + "老挝": "寮國", + "沈阳": "瀋陽", + "战栗": "顫慄", + "豆蔻": "荳蔻", + "累累": "纍纍", + "阿里": "阿里", + "跟斗": "觔斗", + "筋斗": "筋斗", + "折冲": "折衝", + "梁折": "樑折", + "松干": "松幹", + "家伙": "傢伙", + "伙夫": "伙伕", + "游斗": "游鬥", + "回游": "迴游", + "云游": "雲遊", + "云宵": "雲霄", + "考卷发": "考卷發", + "发卷": "髮卷", + "烟卷": "菸卷", + "连卷": "連卷", + "充电宝": "行動電源", + "排插": "延長綫", + "文件夹": "檔案夾", + "打伞": "撐傘", + "洗面奶": "洗面乳", + "洗发水": "洗髮乳", + "打底裤": "内搭褲", + "电饭煲": "電鍋", + "发卡": "髮夾", + "聊天群": "聊天視窗", + "普通话": "國語", + "简历": "履歷", + "公交车": "公車", + "打车": "叫車", + "出租车": "計程車", + "地铁": "捷運", + "自行车": "脚踏車", + "摩托车": "機車", + "巴士": "客運", + "奔驰": "賓士", + "挺好的": "滿好的", + "牛逼": "厲害", + "左拐": "左轉", + "估计": "大概", + "竖的": "直的", + "让一下": "借過", + "凉水": "冰水", + "打包": "外帶", + "外卖": "外送", + "很火": "很紅", + "宾馆": "飯店", + "旅馆": "賓館", + "包间": "包廂", + "卫生间": "化妝室", + "幼儿园": "幼稚園", + "公安局": "警察局", + "饭店": "餐廳", + "酒店": "飯店", + "高校": "大學", + "写字楼": "辦公大樓", + "换乘站": "轉運站", + "豆腐脑": "豆花", + "菠萝": "鳳梨", + "薯片": "洋芋片", + "土豆": "馬鈴薯", + "花生": "土豆", + "芝士": "起司", + "猕猴桃": "奇異果", + "盒饭": "便當", + "夜宵": "宵夜", + "金枪鱼": "鮪魚", + "三文鱼": "鮭魚", + "番石榴": "芭樂", + "冰激淋": "冰淇淋", + "冰棍": "冰棒", + "快餐": "速食", + "格斗": "挌鬥", + "西红柿": "番茄", + "西兰花": "花椰菜", + "创可贴": "OK綳", + "输液": "打點滴", + "献血": "捐血", + "B超": "超音波檢查", + "疯牛病": "狂牛病", + "台球": "撞球", + "乒乓球": "桌球", + "自由泳": "自由式", + "蛙泳": "蛙式", + "初中生": "國中生", + "本科生": "大學生", + "传销": "直銷", + "宇航员": "太空人", + "超声波": "超音波", + "北京时间": "中原標準時間", + "保质期": "保存期限", + "甲肝": "A肝", + "乙肝": "B肝", + "丙肝": "C肝", + "塑料": "塑膠", + "够不到": "搆不到", + "够不着": "搆不着", + "舞娘": "舞孃", + "秋千": "鞦韆", + "拐杖": "枴杖", + "剩余": "賸餘", + "胡同": "衚衕", + "个旧": "箇舊縣", + "朱砂": "硃砂", + "知识产权": "智慧財產權", + "·布尔": "·布爾", + "128 位": "128 位元", + "128位": "128位元", + "32 位": "32 位元", + "32位": "32位元", + "360 搜索": "360 搜索", + "360 综合搜索": "360 綜合搜索", + "360搜索": "360搜索", + "360综合搜索": "360綜合搜索", + "64 位": "64 位元", + "64位": "64位元", + "80 位": "80 位元", + "80位": "80位元", + "A 盘": "本機磁碟 (A)", + "A盘": "本機磁碟(A)", + "B 盘": "本機磁碟 (B)", + "BC 范式": "BC 正規形式", + "BC范式": "BC正規形式", + "B盘": "本機磁碟(B)", + "C 盘": "本機磁碟 (C)", + "C++ 的类": "C++ 的類別", + "C++ 的类型": "C++ 的類型", + "C++ 类": "C++ 類別", + "C++ 类似": "C++ 類似", + "C++ 类型": "C++ 類型", + "C++的类": "C++的類別", + "C++的类型": "C++的類型", + "C++类": "C++類別", + "C++类似": "C++類似", + "C++类型": "C++類型", + "C盘": "本機磁碟(C)", + "D 盘": "本機磁碟 (D)", + "Device Stage": "裝置舞台", + "DK 范式": "DK 規格化", + "DK范式": "DK規格化", + "DVD Maker": "DVD 製作程式", + "D盘": "本機磁碟(D)", + "E 盘": "本機磁碟 (E)", + "Enter 键": "RETURN 鍵", + "Enter键": "RETURN鍵", + "E盘": "本機磁碟(E)", + "F 盘": "本機磁碟 (F)", + "F盘": "本機磁碟(F)", + "G 盘": "本機磁碟 (G)", + "Google 云消息传递": "Google 雲端通訊", + "Google 工具条": "Google 工具列", + "Google 文档": "Google 文件", + "Google 视频": "Google 影片", + "Google云消息传递": "Google雲端通訊", + "Google工具条": "Google工具列", + "Google文档": "Google文件", + "Google视频": "Google影片", + "GSM 移动": "GSM 行動", + "GSM移动": "GSM行動", + "GUID 分区表": "GUID 磁碟分割表", + "GUID分区表": "GUID磁碟分割表", + "G盘": "本機磁碟(G)", + "H 盘": "本機磁碟 (H)", + "H盘": "本機磁碟(H)", + "I 盘": "本機磁碟 (I)", + "Internet 双陆棋": "網際網路西洋骰子棋", + "Internet 跳棋": "網際網路西洋棋", + "Internet 黑桃王": "網際網路西式拱豬", + "IP核": "矽智財", + "I盘": "本機磁碟(I)", + "J 盘": "本機磁碟 (J)", + "Java 的类": "Java 的類別", + "Java 的类型": "Java 的類型", + "Java 类": "Java 類別", + "Java 类似": "Java 類似", + "Java 类型": "Java 類型", + "Java的类": "Java的類別", + "Java的类型": "Java的類型", + "Java类": "Java類別", + "Java类似": "Java類似", + "Java类型": "Java類型", + "J盘": "本機磁碟(J)", + "K 盘": "本機磁碟 (K)", + "K盘": "本機磁碟(K)", + "L 盘": "本機磁碟 (L)", + "L盘": "本機磁碟(L)", + "M 盘": "本機磁碟 (M)", + "M盘": "本機磁碟(M)", + "N 盘": "本機磁碟 (N)", + "N盘": "本機磁碟(N)", + "O 盘": "本機磁碟 (O)", + "O盘": "本機磁碟(O)", + "P 盘": "本機磁碟 (P)", + "PN 结": "PN 接面", + "P-N 结": "P-N 接面", + "PN结": "PN接面", + "P-N结": "P-N接面", + "P盘": "本機磁碟(P)", + "Q 盘": "本機磁碟 (Q)", + "Q盘": "本機磁碟(Q)", + "R 盘": "本機磁碟 (R)", + "R盘": "本機磁碟(R)", + "S 盘": "本機磁碟 (S)", + "Sun 微系统": "昇陽電腦", + "Sun微系统": "昇陽電腦", + "S盘": "本機磁碟(S)", + "T 盘": "本機磁碟 (T)", + "T盘": "本機磁碟(T)", + "USB 数字电视棒": "USB 數位電視棒", + "USB 电视棒": "USB 電視棒", + "USB数字电视棒": "USB數位電視棒", + "USB电视棒": "USB電視棒", + "V 盘": "本機磁碟 (V)", + "V盘": "本機磁碟(V)", + "W 盘": "本機磁碟 (W)", + "Windows 接口": "Windows 介面", + "Windows 控制面板": "Windows 控制台", + "Windows 日记本": "Windows 筆記本", + "Windows 照片查看器": "Windows 相片檢視器", + "Windows接口": "Windows介面", + "Windows控制面板": "Windows控制台", + "Windows日记本": "Windows筆記本", + "Windows照片查看器": "Windows相片檢視器", + "W盘": "本機磁碟(W)", + "X 盘": "本機磁碟 (X)", + "X盘": "本機磁碟(X)", + "Y 盘": "本機磁碟 (Y)", + "Y盘": "本機磁碟(Y)", + "Z 盘": "本機磁碟 (Z)", + "Z盘": "本機磁碟(Z)", + "七号信令系统": "第七號發信系統", + "七段数码管": "七段顯示器", + "万维网": "全球資訊網", + "万维网联盟": "全球資訊網協會", + "三叉搜索树": "三元搜尋樹", + "三叉树": "三元樹", + "三叉链表": "三元連結串列", + "上下文切换": "上下文交換", + "上网本": "小筆電", + "下划线": "底線", + "下拉列表": "下拉式清單", + "下拉菜单": "下拉式選單", + "下溢": "欠位", + "与门": "及閘", + "与非逻辑": "反及邏輯", + "与非门": "反及閘", + "专用集成电路": "特殊應用積體電路", + "世界互联网大会": "世界互聯網大會", + "世界移动通信大会": "世界行動通訊大會", + "丢失": "遺失", + "个人数码助理": "個人數位助理", + "个人网": "個人區域網路", + "个性化": "個人化", + "中端": "中階", + "中级": "中階", + "中间件": "中介軟體", + "丰富互联网应用程序": "多樣化網際網路應用程式", + "串口": "序列埠", + "串行": "序列", + "串行端口": "序列埠", + "串行计算": "序列計算", + "主存": "主記憶體", + "主引导记录": "主開機紀錄", + "主板": "主機板", + "主页": "首頁", + "主题": "佈景主題", + "乐视云计算": "樂視雲計算", + "乔布斯": "賈伯斯", + "九段数码管": "九段顯示器", + "书写器": "小作家", + "二叉": "二元", + "二叉堆": "二元堆積", + "二叉搜索树": "二元搜尋樹", + "二叉树": "二元樹", + "二叉链表": "二元連結串列", + "二极管": "二極體", + "二进制补码": "二補數", + "云存储": "雲端儲存", + "云盘": "雲端硬碟", + "云计算": "雲端運算", + "互信息": "相互資訊", + "互动娱乐": "互動娛樂", + "互动百科": "互動百科", + "互联网": "網際網路", + "互联网信息办公室": "互聯網信息辦公室", + "互联网内容提供商": "線上內容提供者", + "互联网应急中心": "互聯網應急中心", + "互联网服务提供商": "網際網路服務提供者", + "互联网络信息中心": "互聯網絡信息中心", + "五笔字型": "五筆字型", + "亚阈值": "次臨界", + "交互": "互動", + "产品密钥": "產品金鑰", + "人工智能": "人工智慧", + "人工神經": "類神經", + "人机界面": "人機介面", + "人渣文本": "人渣文本", + "人脸识别": "臉部辨識", + "介质": "媒介", + "介质相关接口": "媒體相依介面", + "他支持": "他支持", + "代码": "程式碼", + "代码生成器": "碼產生器", + "代码表": "代碼表", + "代码页": "頁碼", + "令牌": "權杖", + "以太网": "乙太網路", + "任务切换": "工作切換", + "任务栏": "工作列", + "任务管理器": "工作管理員", + "任务视图": "工作檢視", + "企业移动管理": "企業行動管理", + "企图学": "企圖學", + "优化": "最佳化", + "优盘": "隨身碟", + "优酷视频": "優酷視頻", + "会话": "對談", + "会话劫持": "連線劫持", + "会话标识": "交談識別碼", + "传感器": "感測器", + "传输门": "傳輸閘", + "伪代码": "虛擬碼", + "伯克利软件套件": "柏克萊軟體套件", + "位串": "位元串", + "位图": "點陣圖", + "位操作": "位元運算", + "位模式": "位元型樣", + "位段": "位元欄", + "低保真": "低傳真", + "低清": "低畫質", + "低端": "低階", + "低级": "低階", + "低级编程语言": "低階程式語言", + "低级语言": "低階語言", + "例程": "常式", + "依存类型": "依存型別", + "依赖类型": "依值型別", + "便携式": "可攜式", + "便携版": "可攜式版本", + "便笺": "自黏便箋", + "保存": "儲存", + "保护继电器": "保護電驛", + "信号": "訊號", + "信号量": "號誌", + "信息": "資訊", + "信息产业": "資訊工業", + "信息及通信技术": "資訊及通訊科技", + "信息学": "資訊學", + "信息安全": "資訊安全", + "信息技术": "資訊科技", + "信息接触": "資訊參與", + "信息时代": "資訊時代", + "信息管理": "資訊管理", + "信息过载": "資訊超載", + "信道": "頻道", + "修饰符": "修飾詞", + "偏置": "偏壓", + "像素": "畫素", + "元数据": "元資料", + "元编程": "元程式設計", + "兆字节": "百萬位元組", + "光伏": "太陽能光電", + "光刻": "微影", + "光刻胶": "光阻劑", + "光掩模": "光罩", + "光标": "游標", + "光电二极管": "光電二極體", + "光盘": "光碟", + "光盘驱动器": "光碟機", + "光纤分布式数据接口": "光纖分散式資料介面", + "光网络终端": "光纖網路終端", + "入门版": "簡易版", + "全局": "全域", + "全局唯一标识分区表": "GUID 磁碟分割表", + "全屏": "全螢幕", + "全息": "全像", + "全球移动通信系统协会": "全球行動通訊系統協會", + "全角": "全形", + "全面屏手机": "全螢幕手機", + "全高清": "超高畫質", + "八叉树": "八元樹", + "公共陆基移动网": "公用陸上行動網路", + "公文包": "公事包", + "共享": "共享", + "共享文件夹": "共用資料夾", + "共享软件": "共享軟體", + "共模抑制比": "共模拒斥比", + "关系数据库": "關聯式資料庫", + "兼容": "相容", + "内容分发网络": "內容傳遞網路", + "内容可寻址存储器": "可定址內容記憶體", + "内核": "核心", + "内核事务管理器": "核心交易管理員", + "内置": "內建", + "内联": "行內", + "内联网": "內部網路", + "内部网": "內部網路", + "内部网络": "內部網路", + "内链": "內部連結", + "冒泡排序": "泡沫排序", + "写保护": "防寫", + "写字板": "WordPad", + "冯·诺伊曼": "馮·紐曼", + "击穿电压": "崩潰電壓", + "函数": "函式", + "函数式": "函數式", + "函数式编程": "函式語言程式設計", + "函数编程语言": "函式程式語言", + "刀片服务器": "刀鋒伺服器", + "分区": "分割區", + "分卷压缩": "分割壓縮", + "分层树形视图": "多層次樹狀介面", + "分层视图": "多層次樹狀介面", + "分布式": "分散式", + "分析器": "剖析器", + "分立器件": "離散元件", + "分组交换": "封包交換", + "分组密码": "區塊加密法", + "分组码": "區塊碼", + "分辨率": "解析度", + "分配单元": "單位配置", + "创建": "建立", + "刷新": "重新整理", + "刷新缓存": "清除快取", + "刻录": "燒錄", + "刻蚀": "蝕刻", + "前向链接": "正向鏈結", + "前缀": "字首", + "剪切": "剪下", + "剪贴板": "剪貼簿", + "办公室套件": "辦公室套件", + "功率因数": "功率因素", + "功能手机": "功能型手機", + "加载": "載入", + "动态类型": "動態型別", + "动态绑定": "動態繫結", + "助记符": "輔助記憶碼", + "匹配": "符合", + "区块链接": "區塊鏈結", + "区域和语言选项": "地區及語言選項", + "十六段数码管": "十六段顯示器", + "十四段数码管": "十四段顯示器", + "半角": "半形", + "协作": "協同運作", + "协议": "協定", + "单元格": "儲存格", + "单参函数": "一元函式", + "单点登录": "單一登入", + "单片系统": "單晶片系統", + "单相串励电动机": "交流整流子電動機", + "单选按钮": "無線電鈕", + "单选框": "無線電鈕", + "单通道": "單連結", + "博客": "部落格", + "博客来": "博客來", + "占位符": "預留位置", + "即插即用": "隨插即用", + "卷影复制": "磁碟區陰影複製", + "厄利效应": "爾利效應", + "压缩包": "壓縮檔", + "原生": "固有", + "参数列表": "參數列", + "参数表": "參數列", + "参考资料": "參考資料", + "双参函数": "二元函數", + "双通道": "雙連結", + "反向": "逆向", + "反码": "一補數", + "反规范化": "解除規格化", + "反链接": "反鏈結", + "反馈": "回饋", + "发射极": "射極", + "发生器": "產生器", + "发短信": "傳簡訊", + "发行": "釋出", + "发送": "傳送", + "受主": "受體", + "变量": "變數", + "叠加定理": "重疊定理", + "句柄": "控制代碼", + "只写": "唯寫", + "只写存储器": "唯寫記憶體", + "只读": "唯讀", + "只读存储器": "唯讀記憶體", + "可变码率": "變動位元速率", + "可执行": "可執行", + "可执行文件": "可執行檔", + "可扩展": "可延伸", + "可扩展商业报告语言": "可延伸商用報告語言", + "可扩展固件接口": "可延伸韌體介面", + "可扩展置标语言": "可延伸標示語言", + "可控硅": "矽控整流器", + "可移动": "抽取式", + "可移植文档格式": "可攜式文件格式", + "可编程逻辑门阵列": "可程式化邏輯閘陣列", + "可编程逻辑阵列": "可程式化邏輯陣列", + "可编程阵列逻辑": "可程式化陣列邏輯", + "可视化": "視覺化", + "可重构计算": "可重組計算", + "台式机": "桌上型電腦", + "吉字节": "吉位元組", + "吉比特以太网": "十億位元乙太網路", + "同或逻辑": "反互斥或邏輯", + "同或门": "反互斥或閘", + "名字空间": "命名空間", + "后台流量": "背景流量", + "后台运行": "背景執行", + "后缀": "字尾", + "向下兼容": "向下相容", + "向导": "精靈", + "启动引导程序": "啟動載入程式", + "启动栏": "啟動列", + "启动盘": "啟動磁碟", + "启动转换": "啟動切換", + "启辉器": "啟動器", + "呼叫转移": "來電轉駁", + "命令列表": "命令列表", + "命令式编程": "指令式程式設計", + "命令提示符": "命令提示字元", + "命令栏": "命令列", + "命令行": "命令列", + "命令链接": "命令鏈結", + "哈希": "雜湊", + "响应": "回應", + "商业模型": "商業模式", + "器件": "元件", + "四叉树": "四元樹", + "回复": "回覆", + "回复原": "回復原", + "回收站": "資源回收筒", + "回调": "回呼", + "回车符": "回車字元", + "回车键": "確認鍵", + "因特网密钥交换": "網際網路金鑰交換", + "固件": "韌體", + "固定电话": "固網電信", + "固定码率": "固定位元速率", + "固实压缩": "結實壓縮", + "国家互联网应急中心": "國家互聯網應急中心", + "国家测绘地理信息局": "國家測繪地理信息局", + "图像文件": "圖檔", + "图像浏览器": "圖片檢視器", + "图形处理器": "圖形處理器", + "图形学": "圖學", + "图形用户界面": "圖形化使用者介面", + "图形计算器": "繪圖計算機", + "图标": "圖示", + "图灵完全": "圖靈完備", + "图灵完备": "圖靈完備", + "土豆视频": "土豆視頻", + "在线": "線上", + "在线视频": "網路影片", + "地图学": "地圖學", + "地址": "位址", + "地址栏": "網址列", + "地面": "無線", + "地面广播": "無線廣播", + "地面数字电视": "數位無線電視", + "地面电视": "無線電視", + "坏道": "壞軌", + "坐标": "座標", + "城域网": "都會網路", + "基于原型的编程": "原型程式設計", + "基于类": "類別為基", + "基于类似": "基於類似", + "基于类型": "基於類型", + "基于类的编程": "類別為基的程式設計", + "基带": "基頻", + "基类": "基礎類別", + "基类型": "基本類型", + "堆排序": "堆積排序", + "堆栈": "堆疊", + "堆栈帧": "堆疊框", + "增强现实": "擴增實境", + "墨球": "筆跡球", + "壁纸": "桌布", + "声卡": "音效卡", + "声明语句": "宣告", + "处理函数": "處理常式", + "复印": "影印", + "复杂度类": "複雜度類別", + "复杂度类似": "複雜度類似", + "复杂性类": "複雜性類別", + "复选按钮": "核取按鈕", + "复选框": "核取方塊", + "外延": "磊晶", + "外置": "外接", + "外置硬盘": "外接硬碟", + "外链": "外部連結", + "外键": "外來鍵", + "多主体系统": "多代理系統", + "多任务": "多工", + "多宿主": "內送流量備援容錯機制", + "多态": "多型", + "多线程": "多緒", + "多谐振荡器": "複振器", + "多选框": "核取方塊", + "多频道网络": "多頻道聯播網", + "大型机": "大型電腦", + "大数据": "巨量資料", + "大规模集成电路": "大型積體電路", + "太字节": "兆位元組", + "太阳能光伏": "太陽能光電", + "头文件": "標頭檔", + "夹断": "夹止", + "套接层": "通訊層", + "她支持": "她支持", + "子例程": "次常式", + "子类型": "子類型", + "子网": "子網路", + "字体": "字型", + "字段": "欄位", + "字符": "字元", + "字符串": "字串", + "字符号": "字符號", + "字符打印机": "字元列印機", + "字符映射表": "字元對應表", + "字符生成器": "字元產生器", + "字节": "位元組", + "字节跳动": "字節跳動", + "存储": "儲存", + "存储卡": "記憶卡", + "存储器": "記憶體", + "存储程序": "儲存程序", + "守护进程": "守護行程", + "安全中心": "資訊安全中心", + "安全套接层": "安全通訊協定", + "安全帐户管理器": "安全性帳戶管理員", + "安全软件": "安全軟體", + "安装包": "安裝套件", + "完全屏蔽": "完全屏蔽", + "完备码": "完整码", + "宏": "巨集", + "宏内核": "單核心", + "宏块": "大區塊", + "宏病毒": "巨集病毒", + "定位框": "定位域", + "定制": "客製化", + "实例方法": "實體方法", + "实时": "即時", + "审核": "稽核", + "客户端": "用戶端", + "家庭": "住家", + "家庭地址": "住家地址", + "家庭普通版": "家用入門版", + "家庭版": "家用版", + "家庭组": "家用群組", + "家庭高级版": "家用進階版", + "家长控制": "家長監護", + "宽屏": "寬螢幕", + "宽带": "寬頻", + "寄存器": "暫存器", + "密码认证协议": "通行碼鑑別協定", + "密钥": "金鑰", + "对话框": "對話方塊", + "对象": "物件", + "对象连接与嵌入": "物件連結與嵌入", + "寻址": "定址", + "寻址模式": "定址模式", + "导入": "匯入", + "导出": "匯出", + "导航条": "導覽列", + "封装内系统": "封裝體系", + "射极跟随器": "射極隨耦器", + "小组": "群組", + "尧字节": "佑位元組", + "尾注": "章節附註", + "尾部递归": "尾端遞迴", + "局域网": "區域網路", + "层次结构": "階層", + "屏幕": "螢幕", + "屏幕保护程序": "螢幕保護裝置", + "屏幕键盘": "螢幕小鍵盤", + "属性": "內容", + "嵌套": "巢狀", + "工业和信息化": "工業和信息化", + "工作组": "工作群組", + "工具栏": "工具列", + "工程": "專案", + "工艺": "製程", + "工频": "電源頻率", + "差错检测码": "誤差檢測碼", + "已保存的搜索": "儲存的搜尋", + "布尔": "布林", + "布尔逻辑": "布林運算", + "帖子": "貼文", + "带圈": "圍繞", + "带圈字符": "圍繞字元", + "带宽": "頻寬", + "帧": "影格", + "帧同步": "影格同步化", + "帧指针": "影格指標", + "帧率": "影格率", + "帮助": "說明", + "帮助与支持": "說明與支援", + "帮助文档": "說明文件", + "常量": "常數", + "平均码率": "平均位元速率", + "平板电脑": "平板電腦", + "并发": "並行", + "并发计算": "並行計算", + "并行": "並列", + "并行端口": "並列埠", + "并行计算": "平行計算", + "幻灯片": "投影片", + "广告位": "廣告區", + "广域网": "廣域網路", + "应用程序": "應用程式", + "应用程序接口": "應用程式介面", + "开启": "開啟", + "开始菜单": "開始功能表", + "开放手持设备联盟": "開放手機聯盟", + "开放移动联盟": "開放行動聯盟", + "异常处理": "例外處理", + "异或": "互斥或", + "异或逻辑": "互斥或邏輯", + "异或门": "互斥或閘", + "异步": "非同步", + "异质结": "異質接面", + "引导": "啟動", + "引用": "參照", + "弱类型": "弱型別", + "弹出窗口": "彈出式視窗", + "强类型": "強型別", + "归并": "合併", + "当且仅当": "若且唯若", + "当前版本": "目前版本", + "当机器": "當機器", + "录像带": "錄影帶", + "彩信": "多媒體簡訊", + "彩屏": "彩色螢幕", + "影片流": "影片串流", + "影音流": "影音串流", + "循环": "迴圈", + "微博": "微網誌", + "微博客": "微部落格", + "微型博客": "微型部落格", + "微比特": "微比特", + "快捷工具栏": "快捷列", + "快捷方式": "捷徑", + "快捷键": "快速鍵", + "性价比": "CP 值", + "性能": "效能", + "总线": "匯流排", + "恢复": "回復", + "恢复光盘": "還原光碟", + "恢复原": "恢復原", + "恢复记录": "恢復記錄", + "情景模式": "音訊設定檔", + "我支持": "我支持", + "我的文档": "我的文件", + "或门": "或閘", + "或非逻辑": "反或邏輯", + "或非门": "反或閘", + "截": "擷", + "截取": "擷取", + "截图": "擷取", + "截图工具": "剪取工具", + "截屏": "螢幕擷取", + "扇区": "磁區", + "手持地面无线": "手持式數位視訊廣播", + "扎克伯格": "祖克柏", + "扒站": "砍站", + "打印": "列印", + "打印机": "印表機", + "打印预览": "預覽列印", + "托管": "代管", + "托管代码": "受控代碼", + "执行者": "執行者", + "扩展 A 区": "擴充 A 區", + "扩展 B 区": "擴充 B 區", + "扩展 C 区": "擴充 C 區", + "扩展 D 区": "擴充 D 區", + "扩展 E 区": "擴充 E 區", + "扩展 F 区": "擴充 F 區", + "扩展 G 区": "擴充 G 區", + "扩展A区": "擴充A區", + "扩展B区": "擴充B區", + "扩展C区": "擴充C區", + "扩展D区": "擴充D區", + "扩展E区": "擴充E區", + "扩展F区": "擴充F區", + "扩展G区": "擴充G區", + "扩展区": "擴充區", + "扩展名": "副檔名", + "扩展支持": "延伸支援", + "扩展汉字": "擴充漢字", + "扩展现实": "延展實境", + "扩谱": "展譜", + "扩频": "展頻", + "扫描仪": "掃描器", + "扫雷": "踩地雷", + "扬声器": "喇叭", + "批处理": "批次處理", + "批处理文件": "批次檔", + "批处理程序": "批次程式", + "批量": "批次", + "投影仪": "投影機", + "抖音短视频": "抖音短視頻", + "抛出": "丟擲", + "抽样": "取樣", + "拍字节": "拍位元組", + "拒绝服务": "阻斷服務", + "持久性": "永續性", + "指针": "指標", + "按位": "按位元", + "捷威": "桀威", + "接入复用器": "接取多工器", + "接入点": "存取點", + "接近传感器": "鄰近感測器", + "控件": "控制項", + "控制面板": "控制台", + "推导": "推導", + "推送": "推播", + "掩模": "光罩", + "掩码": "遮罩", + "提交": "送出", + "搜狐博客": "搜狐博客", + "搜狐视频": "搜狐視頻", + "搜狗搜索": "搜狗搜索", + "搜索": "搜尋", + "搜索关键字": "搜尋鍵碼", + "搜索框": "搜尋方塊", + "摄像头": "網路攝影機", + "摄像机": "攝錄影機", + "撤销": "復原", + "播客": "Podcast", + "操作中心": "重要訊息中心", + "操作对象": "運算物件", + "操作数": "運算元", + "操作系统": "作業系統", + "支持": "支援", + "支持他": "支持他", + "支持向量": "支持向量", + "支持她": "支持她", + "支持我": "支持我", + "支持者": "支持者", + "收藏夹": "我的最愛", + "放大区": "主動區", + "散列": "雜湊", + "数字": "數位", + "数字信号处理器": "數位訊號處理器", + "数字化": "數位化", + "数字发行": "數位發行", + "数字图像": "數位影像", + "数字地面电视": "數位無線電視", + "数字媒体": "數位媒體", + "数字广播": "數位廣播", + "数字模式": "數位模式", + "数字模拟转换器": "數位類比轉換器", + "数字水印": "數位浮水印", + "数字测图": "數位製圖", + "数字照片": "數位相片", + "数字电视": "數位電視", + "数字相机": "數位相機", + "数字移动": "數位行動", + "数字签名": "數位簽章", + "数字视频": "數位影片", + "数字证书": "數位憑證", + "数字资产": "數位資產", + "数字身份": "數位身分", + "数据": "資料", + "数据中心": "資料中心", + "数据仓库": "資料倉儲", + "数据包": "封包", + "数据包含": "資料包含", + "数据包括": "資料包括", + "数据帧": "資料框", + "数据库": "資料庫", + "数据报文": "資料報", + "数据挖掘": "資料探勘", + "数据捕捞": "資料挖掘", + "数据清洗": "資料淨化", + "数据源": "資料來源", + "数据选择器": "數據多工器", + "数据链接": "資料鏈結", + "数据集市": "資料市集", + "数码视讯": "數碼視訊", + "数码通": "數碼通", + "数组": "陣列", + "文件": "檔案", + "文件主名": "主檔名", + "文件名": "檔名", + "文件名字": "檔案名字", + "文件名字空间": "檔案命名空間", + "文件名称": "檔案名稱", + "文件复制服务": "檔案複寫服務", + "文件扩展名": "副檔名", + "文件描述符": "檔案描述子", + "文件管理器": "檔案管理員", + "文件系统": "檔案系統", + "文件资源管理器": "檔案總管", + "文字体系": "文字體系", + "文字处理": "文書處理", + "文字处理器": "文書處理器", + "文本": "文字", + "文本文件": "文字檔案", + "文本框": "文字方塊", + "文本编辑器": "文字編輯器", + "文档": "文件", + "文档对象模型": "文件物件模型", + "文档文件": "文件檔案", + "斯诺登": "史諾登", + "新浪博客": "新浪博客", + "新浪视频": "新浪視頻", + "方程式": "方程式", + "施主": "施體", + "施乐": "全錄", + "施密特触发器": "施密特觸發器", + "旗舰版": "旗艦版", + "无损": "無失真", + "无损压缩": "無失真壓縮", + "无源滤波器": "被動式濾波器", + "无用信息": "多餘的資料", + "日历": "行事曆", + "日历程序": "行事曆程式", + "日志": "紀錄檔", + "时分": "分時", + "时分复用": "分時多工", + "时分多址": "分時多重進接", + "时钟门控": "時脈閘控", + "时间脉冲信号": "定時器訊號", + "时隙": "時槽", + "易失性": "揮發性", + "映射": "對映", + "显像管": "映像管", + "显卡": "顯示卡", + "显存": "視訊記憶體", + "显示卡": "視訊卡", + "显示器": "監視器", + "显示屏": "顯示器", + "晶体管": "電晶體", + "晶闸管": "閘流體", + "智能": "智慧型", + "智能 ABC": "智能 ABC", + "智能ABC": "智能ABC", + "智能化": "智慧化", + "智能卡": "智慧卡", + "智能型": "智慧型", + "智能手机": "智慧型手機", + "智能手表": "智慧型手錶", + "智能电视": "智慧型電視", + "智能音箱": "智慧型喇叭", + "最优": "最佳", + "最优先": "最優先", + "最优秀": "最優秀", + "最优美": "最優美", + "最优质": "最優質", + "最底层派生类": "最末層衍生類別", + "最终用户": "終端使用者", + "月光博客": "月光博客", + "有损": "失真", + "有损压缩": "失真壓縮", + "有源": "主動", + "服务器": "伺服器", + "服务器消息块": "伺服器訊息區塊", + "服务器阵列": "伺服器陣列", + "服务套餐": "服務專案", + "服务框架": "服務架構", + "服务端": "伺服器端", + "本地": "本機", + "本地化": "在地化", + "机器代码": "機器碼", + "机顶盒": "機上盒", + "杀毒": "防毒", + "权标": "符記", + "权限": "許可權", + "构造函数": "建構函式", + "析构": "解構", + "析构函数": "解構函式", + "枚举": "列舉", + "枚举器": "列舉元", + "枚举成员": "列舉元", + "果冻豆": "雷根糖", + "查找": "尋找", + "查看": "檢視", + "栅极": "閘極", + "标头": "檔頭", + "标清": "標準畫質", + "标签页": "分頁", + "标识符": "識別碼", + "标量": "純量", + "标题栏": "標題列", + "校园网": "校園網路", + "格芯": "格羅方德", + "框图": "方塊圖", + "桌面型": "桌上型", + "桌面版": "電腦版", + "档案室": "檔案室", + "档案馆": "檔案館", + "梦幻桌面": "DreamScene", + "检错码": "偵錯碼", + "检验位": "核對位元", + "检验和": "核對和", + "模块": "模組", + "模式": "範式", + "模式识别": "圖型識別", + "模拟": "類比", + "模拟器": "模擬器", + "模拟广播": "類比廣播", + "模拟数字转换器": "類比數位轉換器", + "模拟现实": "模擬實境", + "模拟电视": "類比電視", + "横屏幕": "橫螢幕", + "正则表达式": "正規表示式", + "正则语言": "正規語言", + "正向": "順向", + "正弦信号": "正弦訊號", + "死机": "當機", + "死锁": "死結", + "残余边带": "殘邊帶", + "比特": "位元", + "比特分": "比特分", + "比特差错": "位元錯誤", + "比特币": "比特幣", + "比特彗星": "比特彗星", + "比特率": "位元速率", + "比特精灵": "比特精靈", + "比特误码率": "位元錯誤率", + "毫比特": "毫比特", + "水印": "浮水印", + "汇编": "組譯", + "汇编语言": "組合語言", + "汉字体系": "漢字體系", + "沃森": "華生", + "沟道": "通道", + "波分复用": "波長分波多工", + "波特": "鮑", + "波特率": "鮑率", + "注入": "資料隱碼", + "注册机": "序號產生器", + "注册表": "登錄檔", + "注册表编辑器": "登錄編輯程式", + "注销": "登出", + "泽字节": "皆位元組", + "活动目录": "Active Directory", + "活锁": "活結", + "派生": "衍生", + "派生类": "衍生類別", + "派生类型": "衍生類型", + "流媒体": "串流媒體", + "流密码": "串流加密法", + "测序": "定序", + "浏览框": "瀏覽域", + "消息": "訊息", + "消息框": "訊息方塊", + "消息认证码": "訊息鑑別碼", + "混合信号": "混訊", + "混合信号集成电路": "混合訊號積體電路", + "混合现实": "混合實境", + "清晰度": "解析度", + "清理缓存": "清除快取", + "渲染": "彩現", + "溃客": "劊客", + "源代码": "原始碼", + "源文件": "原始檔", + "滑块": "滾軸", + "滚动": "捲動", + "滚动更新": "滾動更新", + "滚动栏": "捲軸", + "滚动框": "捲動方塊", + "漏极": "汲極", + "演示稿": "簡報", + "澳门增补字符集": "澳門增補字符集", + "澳门资讯系统字集": "澳門資訊系統字集", + "激光": "雷射", + "激光视盘": "雷射影碟", + "激励表": "激發表", + "激活": "啟用", + "激活函数": "啟用功能", + "火山小视频": "火山小視頻", + "点击": "點選", + "点对点": "對等", + "照片": "相片", + "照片库": "相片圖庫", + "照片查看器": "相片檢視器", + "照相手机": "照相手機", + "父类": "父類別", + "物理内存": "實體記憶體", + "物理地址": "實體位址", + "物理层": "實體層", + "特丽珑": "特麗霓虹", + "状态栏": "狀態列", + "玩家国度": "玩家共和國", + "用户": "使用者", + "用户名": "使用者名稱", + "用户帐户控制": "使用者帳戶控制", + "用户框": "使用者方塊", + "用户界面": "使用者介面", + "用户组": "使用者群組", + "用户页": "使用者頁面", + "电信": "電信", + "电信业": "電信業", + "电信公司": "電信公司", + "电信商": "電信商", + "电信服务": "電信服務", + "电信行业": "電信行業", + "电信运营商": "電信業者", + "电图学": "電圖學", + "电子表格": "電子試算表", + "电子计算机": "電腦", + "电子迁移率": "電子移動率", + "电子邮件": "電子郵件", + "电影片": "電影片", + "电气工程": "電機工程", + "电源保护": "不斷電系統", + "电视频": "電視頻", + "画图": "小畫家", + "疑难解答": "疑難排解", + "登录": "登入", + "白炽灯": "白熾燈", + "百度云计算": "百度雲計算", + "百度搜索": "百度搜索", + "百度相册": "百度相冊", + "百度视频": "百度視頻", + "皮肤": "外觀", + "监控": "監視", + "盖茨": "蓋茲", + "盘符": "磁碟機代號", + "目标代码": "目的碼", + "目标文件": "目的檔案", + "目标用户": "目標使用者", + "目标软件": "目標軟體", + "相册": "相簿", + "矢量": "向量", + "矢量图形": "向量圖形", + "短信": "簡訊", + "短视频": "短影音", + "码分": "分碼", + "码分多址": "分碼多重進接", + "码率": "位元速率", + "硅": "矽", + "硬件": "硬體", + "硬烘干": "硬烤", + "硬盘": "硬碟", + "硬盘阵列": "硬碟陣列", + "硬盘驱动器": "硬碟機", + "硬编码": "寫死", + "磁头划碰": "磁頭損壞", + "磁盘": "磁碟", + "磁盘清理": "磁碟清理", + "磁盘碎片整理": "磁碟重組", + "磁盘碎片整理程序": "磁碟重組工具", + "磁盘阵列": "磁碟陣列", + "磁盘驱动器": "磁碟機", + "磁道": "磁軌", + "示例": "範例", + "社交媒体": "社群媒體", + "社交网站": "社群網站", + "社交网络": "社群網路", + "社会媒体": "社群媒體", + "社区": "社群", + "移动中心": "行動中心", + "移动互联网": "行動網際網路", + "移动产品": "行動產品", + "移动代理": "行動代理", + "移动代码": "行動程式碼", + "移动信息设备配置文件": "行動資訊裝置設定檔", + "移动公司": "行動公司", + "移动内容管理": "行動內容管理", + "移动客户端": "行動用戶端", + "移动平台": "行動平台", + "移动广播": "行動廣播", + "移动应用": "行動應用", + "移动应用管理": "行動應用管理", + "移动性": "行動性", + "移动操作系统": "行動作業系統", + "移动支付": "行動支付", + "移动数据": "行動資料", + "移动浏览器": "行動瀏覽器", + "移动版": "行動版", + "移动版块": "移動版塊", + "移动版面": "移動版面", + "移动电信": "行動電信", + "移动电信运营商": "行動電信業者", + "移动电源": "行動電源", + "移动电视": "行動電視", + "移动电话": "行動電話", + "移动硬盘": "行動硬碟", + "移动端": "行動端", + "移动终端": "行動終端", + "移动网络": "行動網路", + "移动网络运营商": "行動網路業者", + "移动联网设备": "行動網路裝置", + "移动计算机": "行動電腦", + "移动设备": "行動裝置", + "移动设备管理": "行動裝置管理", + "移动软件": "行動軟體", + "移动运营商": "行動業者", + "移动通信": "行動通訊", + "移相键控": "相位移鍵", + "程序": "程式", + "程序员": "程式設計師", + "程序编写员": "程式設計師", + "程序设计": "程式設計", + "空串": "空字串", + "空分复用": "空間多工", + "空分多址": "分空間多重進接", + "空列表": "空串列", + "空当接龙": "新接龍", + "空穴": "電洞", + "窄带": "窄頻", + "窗体": "表單", + "窗口": "視窗", + "窗口管理器": "視窗管理員", + "站点标识按钮": "網站識別鈕", + "竞争冒险": "競爭危害", + "端口转发": "通訊埠轉發", + "笔记本电脑": "筆記型電腦", + "第一范式": "第一規格化", + "第三范式": "第三正規化", + "第二范式": "第二正規化", + "第五范式": "第五規格化", + "第六范式": "第六規格化", + "第四范式": "第四規格化", + "答复": "答覆", + "签名": "簽章", + "算法": "演算法", + "类加载器": "類別載入器", + "类变量": "類別變數", + "类型": "型別", + "类型代码": "類型代碼", + "类型检查": "型別檢查", + "类型系统": "型別系統", + "类声明": "類別宣告", + "类定义": "類別定義", + "类实例": "類別實例", + "类库": "類別館", + "类成员": "類別成員", + "类方法": "類別方法", + "类模板": "類別模板", + "类的实例": "類別的實例", + "类的构造函数": "類別的建構函數", + "类的析构函数": "類別的破壞函數", + "粘贴": "貼上", + "系统盘": "系統磁碟", + "系统资源管理器": "系統資源管理員", + "系统配置": "系統設定", + "系统配置实用程序": "系統設定公用程式", + "索尼移动": "索尼行動", + "索尼移动通信": "索尼行動通訊", + "繁体": "正體", + "纠错码": "錯誤更正碼", + "红心大战": "傷心小棧", + "纸牌": "接龍", + "纹波": "漣波", + "线程": "執行緒", + "组件": "元件", + "组合框": "組合方塊", + "组提示": "群組提示", + "组策略": "群組原則", + "组群": "群組", + "组链接": "塊鏈結", + "终端": "終端機", + "终结器": "終端子", + "绑定": "繫結", + "结合存储": "可定址內容記憶體", + "结型": "接面型", + "结型场效应管": "接面場效電晶體", + "绘文字": "繪文字", + "绝缘栅双极晶体管": "絕緣閘雙極電晶體", + "统一渲染架构": "統一著色器架構", + "继承列表": "衍化列", + "维基共享资源": "維基共享資源", + "维基数据": "維基數據", + "绿色版": "可攜式版本", + "绿色软件": "可攜式軟體", + "缓冲器": "緩衝區", + "缓冲存储器": "快取記憶體", + "缓存": "快取", + "缓存溢出": "緩衝區溢位", + "编程范型": "程式設計範式", + "编程语言": "程式語言", + "编辑栏": "編輯列", + "缩略网址": "縮網址", + "缩进": "縮排", + "网上论坛": "網路論壇", + "网上邻居": "網路上的芳鄰", + "网关": "閘道器", + "网卡": "網路卡", + "网吧": "網咖", + "网易博客": "網易博客", + "网易相册": "網易相冊", + "网易视频": "網易視頻", + "网景导航者": "網景領航員", + "网格线": "格線", + "网民": "網友", + "网民报告": "網民報告", + "网状数据库": "網狀式資料庫", + "网盘": "網路硬碟", + "网络": "網路", + "网络动画": "網路動畫", + "网络安全和信息化": "網絡安全和信息化", + "网络广播电视台": "網絡廣播電視台", + "网络文化": "網路文化", + "网络欺凌": "網路霸凌", + "网络漫画": "網路漫畫", + "网络电视台": "網絡電視台", + "网络硬盘": "網路硬碟", + "网络购物": "網路購物", + "网络运营商": "網路業者", + "网路电视台": "網路電視台", + "置标语言": "標示語言", + "美国在线": "美國線上", + "耗尽": "空乏", + "耗尽层": "空乏層", + "联机": "連線", + "联机交易处理": "線上異動處理", + "联机分析处理": "連線分析處理", + "联系": "連絡", + "联系人": "聯絡人", + "肖特基": "蕭特基", + "脉冲": "脈波", + "脉冲逆变器": "變流器", + "脑机接口": "人機介面", + "脚本": "指令碼", + "脚本小子": "腳本小子", + "脚本语言": "手稿語言", + "脚注": "註腳", + "脱机": "離線", + "脸书": "臉書", + "腾讯云计算": "騰訊雲計算", + "腾讯博客": "騰訊博客", + "腾讯视频": "騰訊視頻", + "自定义": "自訂", + "自底向上": "由下而上", + "自述文件": "讀我檔案", + "艾字节": "艾位元組", + "节能灯": "省電燈泡", + "芯片": "晶片", + "英伟达": "輝達", + "范型": "範式", + "草榴社区": "草榴社區", + "荷码率": "位元速率", + "获取": "取得", + "菊花链接": "菊式鏈結", + "营销": "行銷", + "著作权": "著作權", + "著作权信息": "著作權資訊", + "蓝屏死机": "藍白當機", + "虚函数": "虛擬函式", + "虚拟专用网": "虛擬私人網路", + "虚拟内存": "虛擬記憶體", + "虚拟机": "虛擬機器", + "蜂窝数据": "蜂巢式資料", + "蜂窝网络": "蜂巢式網路", + "蜘蛛纸牌": "連環新接龍", + "补码": "二補數", + "表情包": "哏圖", + "表格": "試算表", + "表达式": "運算式", + "衬底": "基板", + "西瓜视频": "西瓜視頻", + "西部数据": "威騰電子", + "覆盖": "覆寫", + "覆铜板": "銅箔基板", + "规范化": "規格化", + "视频处理器": "影像處理器", + "视频接口": "視訊連接頭", + "视频文件": "視訊檔", + "视频文档": "視訊檔案", + "视频档": "視訊檔", + "视频游戏": "電動遊戲", + "视频轨": "視訊軌", + "视频输入": "視訊輸入", + "视频输出": "視訊輸出", + "解引用": "解除參照", + "解释器": "直譯器", + "解释型语言": "直譯語言", + "触发器": "正反器", + "触屏": "觸控螢幕", + "触摸": "輕觸", + "触摸屏": "觸控式螢幕", + "触摸板": "觸控板", + "计划任务": "工作排程器", + "计算机": "電腦", + "计算机体系结构": "電腦架構", + "计算机科学": "電腦科學", + "讲述人": "朗讀程式", + "论坛": "論壇", + "设备": "裝置", + "设备上下文": "裝置內容", + "设备环境": "裝置環境", + "设备管理器": "裝置管理員", + "设置": "設定", + "访问学者": "訪問學者", + "访问控制表": "存取控制列表", + "访问量": "瀏覽量", + "证书": "憑證", + "评测系统": "解題系統", + "识别": "辨識", + "译码": "解碼", + "试图学": "試圖學", + "语义": "語意", + "语义网": "語意網", + "语句": "語句", + "语法高亮": "語法突顯", + "语言包": "語言套件", + "语音识别": "語音辨識", + "误码率": "誤碼率", + "请勿追踪": "停止追蹤", + "诺顿克隆精灵": "諾頓魅影系統", + "读卡器": "讀卡機", + "调制": "調變", + "调制解调器": "數據機", + "调度": "排程", + "调度器": "排程器", + "调用层接口": "呼叫層級介面", + "调色板": "調色盤", + "调试": "除錯", + "谷歌": "Google", + "谷歌云消息传递": "Google 雲端通訊", + "谷歌工具条": "Google 工具列", + "谷歌文档": "Google 文件", + "谷歌浏览器内嵌框架": "Google Chrome 內嵌瀏覽框", + "谷歌视频": "Google 影片", + "谷翔信息技术": "谷翔信息技術", + "账号": "帳號", + "账户": "帳戶", + "贪心法": "貪婪法", + "贪心算法": "貪婪演算法", + "贴靠": "貼齊", + "资源管理器": "檔案總管", + "资讯台": "資訊台", + "资讯频道": "資訊頻道", + "赋值运算符": "設定運算子", + "超大规模集成电路": "超大型積體電路", + "超文本标记语言": "超文件標示語言", + "超文本置标语言": "超文件標示語言", + "超时": "逾時", + "超极本": "超極致筆電", + "超编程": "超程式設計", + "超高清": "超高畫質", + "身份": "身分", + "转义": "跳脫", + "转换": "轉檔", + "软件": "軟體", + "软件包": "軟體套件", + "软件包管理系统": "軟體套件管理系統", + "软件开发工具包": "軟體開發套件", + "软件过程": "軟體流程", + "软烘干": "軟烤", + "软盘": "軟碟", + "软盘驱动器": "軟碟機", + "轻松访问": "輕鬆存取", + "载流子": "載子", + "边栏": "資訊看板", + "过程化": "程序化", + "过程式": "程序式", + "过程生成": "程序化生成", + "运算符": "運算子", + "运算符号": "運算符號", + "运行": "執行", + "进程控制块": "過程控制段", + "进程组": "行程群組", + "进程间": "行程間", + "进程间通信": "行程間通訊", + "远程": "遠端", + "远程桌面协议": "遠端桌面協定", + "远程过程调用": "遠端程序呼叫", + "连接": "連線", + "连续互通": "接續互通", + "退出应用程序": "結束應用程式", + "退出程序": "結束程式", + "适配器": "配接器", + "逆变器": "變流器", + "选项卡": "索引標籤", + "递归": "遞迴", + "通信": "通訊", + "通信学": "通訊學", + "通信顺序进程": "交談循序程式", + "通用串行总线": "通用序列匯流排", + "通用分组无线服务": "通用封包無線服務", + "通用序列总线": "通用序列匯流排", + "通讯录": "通訊錄", + "通配符": "萬用字元", + "逻辑卷管理": "邏輯捲軸管理", + "逻辑器件": "邏輯裝置", + "逻辑门": "邏輯閘", + "邮件列表": "郵寄清單", + "邮箱": "電子信箱", + "部分": "部份", + "配置": "組態", + "采样定理": "取樣定理", + "重启": "重新啟動", + "重命名": "重新命名", + "重复组": "重複群", + "重定向": "重新導向", + "重定向页": "重新導向頁面", + "重码率": "重碼率", + "重置": "重設", + "重装": "重灌", + "金卤灯": "高強度氣體放電燈", + "金属氧化物半导体": "金氧半導體", + "金属氧化物半导体场效应管": "金屬氧化物半導體場效電晶體", + "钩子": "勾點", + "链接反向": "鏈結反向", + "链接搜索": "鏈結搜尋", + "链接正向": "鏈結正向", + "链表": "連結串列", + "锁存器": "閂鎖", + "锁定": "釘選", + "键盘布局": "鍵盤配置", + "镇流器": "安定器", + "镜像": "映象", + "门户系统": "入口網站", + "门户网站": "入口網站", + "门电路": "閘電路", + "闪存": "快閃記憶體", + "闪存盘": "隨身碟", + "闪迪": "新帝", + "队列": "佇列", + "阵列服务器": "陣列伺服器", + "阵列硬盘": "陣列硬碟", + "阿里云计算": "阿里雲計算", + "阿里巴巴网络": "阿里巴巴網絡", + "附件": "附屬應用程式", + "附加组件": "附加元件", + "随机存储器": "隨機存取記憶體", + "随机存取": "隨機存取", + "随机数": "亂數", + "隐身模式": "無痕模式", + "集成": "整合", + "集成开发环境": "整合式開發環境", + "集成数字增强网络": "整合數位強化網路", + "集成电路": "積體電路", + "集成设备电路": "整合裝置電路", + "集群": "叢集", + "雪崩击穿": "突崩潰", + "静态类型": "靜態型別", + "非门": "反閘", + "面向代理编程": "代理人導向程式設計", + "面向堆栈": "堆疊導向", + "面向对象": "物件導向", + "面向对象编程": "物件導向程式設計", + "面向并发": "平行導向", + "面向文档": "文件導向", + "面向消息": "訊息導向", + "面向消息的中间件": "訊息導向中介層", + "面向类": "類別導向", + "面向语言的程序设计": "語言導向程式設計", + "面向过程": "程序導向", + "音频": "音訊", + "音频文件": "音訊檔", + "音频文档": "音訊檔", + "音频档": "音訊檔", + "音频轨": "音訊軌", + "音频输入": "音訊輸入", + "音频输出": "音訊輸出", + "页眉": "頁首", + "页脚": "頁尾", + "项目页": "計畫頁", + "频分": "分頻", + "频分复用": "分頻多工", + "频分多址": "分頻多重進接", + "风河": "溫瑞爾", + "飞兆半导体": "快捷半導體", + "飞兆半导体公司": "快捷半導體公司", + "飞行模式": "飛航模式", + "首席信息官": "資訊長", + "首席执行官": "執行長", + "首席技术官": "技術長", + "首席运营官": "營運長", + "首选项": "偏好設定", + "香农": "夏農", + "香港增补字符集": "香港增補字符集", + "驱动程序": "驅動程式", + "高亮": "突顯", + "高亮度": "高亮度", + "高亮显示": "突出顯示", + "高保真": "高傳真", + "高清": "高畫質", + "高清多媒体界面": "高畫質多媒體介面", + "高清晰": "高解析", + "高清音质": "高音質", + "高清音频": "高音質音訊", + "高端": "高階", + "高级": "進階", + "高级编程语言": "高階程式語言", + "高级语言": "高階語言", + "高速缓冲存储器": "高速緩衝記憶體", + "鲍尔默": "巴爾默", + "鸭子类型": "鴨子型別", + "黑客": "駭客", + "黑屏": "黑畫面", + "黑盒测试": "黑箱測試", + "默认": "預設", + "鼠标": "滑鼠", + "齐纳二极管": "稽納二極體", + "不可改变": "不可變造", + "不可变性": "不可變造性", + "防串通": "防勾結", + "操作码": "opcode", + "网桥": "橋接器", + "无许可": "非許可制", + "瘦客户端": "精簡型用戶端", + "最新消息": "最新資訊", + "发送邮件": "傳送電郵", + "通过": "透過", + "图灵不完全": "圖靈不完備", + "了解": "瞭解", + "顺序计算": "循序計算", + "U 盘": ["USB 磁碟機", "USB 隨身碟"], + "U盘": ["USB磁碟機", "USB隨身碟"], + "X 窗口系统": ["X Window 系統", "X 視窗系統"], + "X窗口系统": ["X Window系統", "X視窗系統"], + "三维电影": ["3D 電影", "3D電影"], + "三维计算机": ["3D 電腦", "3D電腦"], + "三维计算机图形": ["3D 電腦圖形", "3D電腦圖形"], + "二维码": ["二維條碼", "行動條碼"], + "信噪比": ["訊號雜訊比", "訊雜比"], + "信息论": ["消息理論", "資訊理論"], + "内存泄漏": ["記憶體流失", "記憶體漏失"], + "前向纠错": ["前向錯誤更正", "正向錯誤校正"], + "单片机": ["單晶片", "微控制器"], + "卸载": ["移除", "解除安裝"], + "可编程": ["可程式化", "可規化"], + "噪声": ["杂讯", "雜訊"], + "套接字": ["通訊端", "通訊端點"], + "子网掩码": ["子網路遮罩", "網路遮罩"], + "屏蔽": ["封鎖", "遮蔽"], + "扩展": ["擴充功能", "擴充套件", "擴充"], + "接口": ["介面", "通訊埠", "埠"], + "插件": ["外掛程式", "外掛"], + "数字版权": ["數位版權", "數位著作權"], + "数据执行保护": ["系統記憶體保護", "資料執行防止"], + "文件夹": ["檔案夾", "資料夾"], + "时钟频率": ["時脈速率", "時脈頻率"], + "最终用户许可协议": ["終端使用者授權協定", "終端使用者授權合約"], + "标记语言": ["標示語言", "標記式語言"], + "模板": ["模板", "範本"], + "流水线": ["管線化", "管線"], + "溢出": ["上限溢位", "溢位"], + "滚动条": ["卷軸", "捲軸"], + "端口": ["通訊埠", "埠"], + "缩略图": ["預覽縮圖", "縮圖"], + "网页快照": ["頁庫存檔", "頁面快取檔"], + "菜单": ["清單", "選單"], + "补丁": ["補靪", "修補程式"], + "视频": ["影片", "視訊"], + "计算器": ["小算盤", "計算機"], + "访问": ["存取", "造訪"], + "调用": ["叫用", "呼叫"], + "质量": ["品質", "质素"], + "跳转列表": ["跳躍功能清單", "跳躍清單"], + "进程": ["處理程序", "行程"], + "退出": ["登出", "結束"], + "配置文件": ["組態檔", "設定檔"], + "采样率": ["取樣率", "取樣頻率"], + "重载": ["多載", "過載"], + "链接": ["連結", "鏈結"], + "项目": ["專案", "計畫"], + "高速缓存": ["快取記憶體", "快取"] + } +} \ No newline at end of file diff --git a/T66y tool/T66y tool.user.js b/T66y tool/T66y tool.user.js index 8b840c1f540..ccffc060607 100644 --- a/T66y tool/T66y tool.user.js +++ b/T66y tool/T66y tool.user.js @@ -13,6 +13,7 @@ (function() { 'use strict'; + const enable1024sDelay = true; const defaultReply = "1024 感謝分享"; var helper = { addCss: function(css) { @@ -189,6 +190,7 @@ quickReply.attr('title', replyStr + "(右击修改)"); var formTitle = $("form td.h>b").text(); function setCountdown() { + if (!enable1024sDelay) return; quickReply.attr("disabled", true); quickReply.css("background", "initial"); var leftTime = parseInt((lastReplyTime - Date.now()) / 1000 + 1025); @@ -297,7 +299,7 @@ let rushTimes = 5; let rushTimer = setInterval(() => { if (--rushTimes > 0) { - requestRush(300); + requestRush(100); } else { clearInterval(rushTimer); rushReply.val("搶簽結束"); @@ -305,7 +307,9 @@ }, 5); } else { if (reachRushMinute) { - if (date.getSeconds() > 57) { + if (date.getSeconds() == 59) { + checkRush(1); + } else if (date.getSeconds() > 57) { checkRush(5); } else if (date.getSeconds() > 50) { checkRush(500); @@ -321,7 +325,7 @@ } }, timeGap); } - rushReply.insertAfter( "form .btn" ); + rushReply.insertAfter( "form .btn:last-child" ); rushReply.click(function() { checkRush(5000); rushReply.attr("disabled", true); 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